From 3aec93dbc9da93b715b53a4545c16d4c59754ef6 Mon Sep 17 00:00:00 2001 From: David Major Date: Sat, 2 May 2015 03:01:06 +1200 Subject: [PATCH 01/10] Bug 1134920 drive-by comment fix. DONTBUILD --- widget/nsPrimitiveHelpers.cpp | 2 +- widget/nsPrimitiveHelpers.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/widget/nsPrimitiveHelpers.cpp b/widget/nsPrimitiveHelpers.cpp index 2683543bdc41..e141e65c7b50 100644 --- a/widget/nsPrimitiveHelpers.cpp +++ b/widget/nsPrimitiveHelpers.cpp @@ -231,7 +231,7 @@ nsPrimitiveHelpers :: ConvertPlatformPlainTextToUnicode ( const char* inText, in // be reallocated regardless (disposing the old buffer is taken care of internally, see // the note below). // -// NOTE: this assumes that it can use nsMemory to dispose of the old buffer. +// NOTE: this assumes that it can use 'free' to dispose of the old buffer. // nsresult nsLinebreakHelpers :: ConvertPlatformToDOMLinebreaks ( const char* inFlavor, void** ioData, diff --git a/widget/nsPrimitiveHelpers.h b/widget/nsPrimitiveHelpers.h index 33c08f2581d2..0d492cb7c1e0 100644 --- a/widget/nsPrimitiveHelpers.h +++ b/widget/nsPrimitiveHelpers.h @@ -56,7 +56,7 @@ public: // be reallocated regardless (disposing the old buffer is taken care of internally, see // the note below). // - // NOTE: this assumes that it can use nsMemory to dispose of the old buffer. + // NOTE: this assumes that it can use 'free' to dispose of the old buffer. static nsresult ConvertPlatformToDOMLinebreaks ( const char* inFlavor, void** ioData, int32_t* ioLengthInBytes ) ; }; // class nsLinebreakHelpers From 967e987b40b8a70ab8438ad923fb281557f7e151 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 1 May 2015 10:07:18 -0500 Subject: [PATCH 02/10] Bug 1129040 - Forward blocklist update notifications to the content process. r=Mossop --- .../mozapps/extensions/nsBlocklistService.js | 17 +++++--- .../extensions/nsBlocklistServiceContent.js | 42 ++++++++++++++++--- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js index 06bda12e9607..cbcfb4e989ab 100644 --- a/toolkit/mozapps/extensions/nsBlocklistService.js +++ b/toolkit/mozapps/extensions/nsBlocklistService.js @@ -298,7 +298,7 @@ function Blocklist() { gPref.addObserver(PREF_EM_LOGGING_ENABLED, this, false); this.wrappedJSObject = this; // requests from child processes come in here, see receiveMessage. - Services.ppmm.addMessageListener("Blocklist::getPluginBlocklistState", this); + Services.ppmm.addMessageListener("Blocklist:getPluginBlocklistState", this); } Blocklist.prototype = { @@ -322,7 +322,7 @@ Blocklist.prototype = { shutdown: function () { Services.obs.removeObserver(this, "xpcom-shutdown"); - Services.ppmm.removeMessageListener("Blocklist::getPluginBlocklistState", this); + Services.ppmm.removeMessageListener("Blocklist:getPluginBlocklistState", this); gPref.removeObserver("extensions.blocklist.", this); gPref.removeObserver(PREF_EM_LOGGING_ENABLED, this); }, @@ -359,7 +359,7 @@ Blocklist.prototype = { // Message manager message handlers receiveMessage: function (aMsg) { switch (aMsg.name) { - case "Blocklist::getPluginBlocklistState": + case "Blocklist:getPluginBlocklistState": return this.getPluginBlocklistState(aMsg.data.addonData, aMsg.data.appVersion, aMsg.data.toolkitVersion); @@ -1192,6 +1192,11 @@ Blocklist.prototype = { return blockEntry.infoURL; }, + _notifyObserversBlocklistUpdated: function () { + Services.obs.notifyObservers(this, "blocklist-updated", ""); + Services.ppmm.broadcastAsyncMessage("Blocklist:blocklistInvalidated", {}); + }, + _blocklistUpdated: function Blocklist_blocklistUpdated(oldAddonEntries, oldPluginEntries) { var addonList = []; @@ -1296,7 +1301,7 @@ Blocklist.prototype = { } if (addonList.length == 0) { - Services.obs.notifyObservers(self, "blocklist-updated", ""); + self._notifyObserversBlocklistUpdated(); return; } @@ -1308,7 +1313,7 @@ Blocklist.prototype = { } catch (e) { LOG(e); } - Services.obs.notifyObservers(self, "blocklist-updated", ""); + self._notifyObserversBlocklistUpdated(); return; } @@ -1342,7 +1347,7 @@ Blocklist.prototype = { if (args.restart) restartApp(); - Services.obs.notifyObservers(self, "blocklist-updated", ""); + self._notifyObserversBlocklistUpdated(); Services.obs.removeObserver(applyBlocklistChanges, "addon-blocklist-closed"); } diff --git a/toolkit/mozapps/extensions/nsBlocklistServiceContent.js b/toolkit/mozapps/extensions/nsBlocklistServiceContent.js index 972daa1a4809..bb24c61008f2 100644 --- a/toolkit/mozapps/extensions/nsBlocklistServiceContent.js +++ b/toolkit/mozapps/extensions/nsBlocklistServiceContent.js @@ -21,6 +21,7 @@ const kMissingAPIMessage = "Unsupported blocklist call in the child process." */ function Blocklist() { + this.init(); } Blocklist.prototype = { @@ -28,12 +29,41 @@ Blocklist.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIBlocklistService]), + init: function () { + Services.cpmm.addMessageListener("Blocklist:blocklistInvalidated", this); + Services.obs.addObserver(this, "xpcom-shutdown", false); + }, + + uninit: function () { + Services.cpmm.removeMessageListener("Blocklist:blocklistInvalidated", this); + Services.obs.removeObserver(this, "xpcom-shutdown", false); + }, + + observe: function (aSubject, aTopic, aData) { + switch (aTopic) { + case "xpcom-shutdown": + this.uninit(); + break; + } + }, + + // Message manager message handlers + receiveMessage: function (aMsg) { + switch (aMsg.name) { + case "Blocklist:blocklistInvalidated": + Services.obs.notifyObservers(null, "blocklist-updated", null); + break; + default: + throw new Error("Unknown blocklist message received from content: " + aMsg.name); + } + }, + /* - * A helper that queries key data from a plugin or addon object - * and generates a simple data wrapper suitable for ipc. We hand - * these directly to the nsBlockListService in the parent which - * doesn't query for much.. allowing us to get away with this. - */ + * A helper that queries key data from a plugin or addon object + * and generates a simple data wrapper suitable for ipc. We hand + * these directly to the nsBlockListService in the parent which + * doesn't query for much.. allowing us to get away with this. + */ flattenObject: function (aTag) { // Based on debugging the nsBlocklistService, these are the props the // parent side will check on our objects. @@ -57,7 +87,7 @@ Blocklist.prototype = { }, getPluginBlocklistState: function (aPluginTag, aAppVersion, aToolkitVersion) { - return Services.cpmm.sendSyncMessage("Blocklist::getPluginBlocklistState", { + return Services.cpmm.sendSyncMessage("Blocklist:getPluginBlocklistState", { addonData: this.flattenObject(aPluginTag), appVersion: aAppVersion, toolkitVersion: aToolkitVersion From 4fbc128cea29df2d53aa19a76edcea4c47ea4330 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 1 May 2015 10:07:19 -0500 Subject: [PATCH 03/10] Bug 1129040 - Provide a way for content processes to query the chrome side blocklist service. r=billm --- dom/ipc/ContentParent.cpp | 22 +++++++++++++++++ dom/ipc/ContentParent.h | 1 + dom/ipc/PContent.ipdl | 5 ++++ dom/plugins/base/nsPluginHost.cpp | 3 ++- dom/plugins/base/nsPluginHost.h | 6 ++++- dom/plugins/base/nsPluginTags.cpp | 41 ++++++++++++++++++------------- 6 files changed, 59 insertions(+), 19 deletions(-) diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 0ee9ba4e0e9a..34fade5903ee 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -161,6 +161,9 @@ #include "private/pprio.h" #include "ContentProcessManager.h" #include "mozilla/psm/PSMContentListener.h" +#include "nsPluginHost.h" +#include "nsPluginTags.h" +#include "nsIBlocklistService.h" #include "nsIBidiKeyboard.h" @@ -1083,6 +1086,25 @@ ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) return mozilla::plugins::SetupBridge(aPluginId, this, true, aRv, &dummy); } +bool +ContentParent::RecvGetBlocklistState(const uint32_t& aPluginId, + uint32_t* aState) +{ + *aState = nsIBlocklistService::STATE_BLOCKED; + + nsRefPtr pluginHost = nsPluginHost::GetInst(); + if (!pluginHost) { + return false; + } + nsPluginTag* tag = pluginHost->PluginWithId(aPluginId); + + if (!tag) { + return false; + } + + return NS_SUCCEEDED(tag->GetBlocklistState(aState)); +} + bool ContentParent::RecvFindPlugins(const uint32_t& aPluginEpoch, nsTArray* aPlugins, diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index a0381c65509d..1baad9904176 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -173,6 +173,7 @@ public: virtual bool RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID) override; virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) override; + virtual bool RecvGetBlocklistState(const uint32_t& aPluginId, uint32_t* aIsBlocklisted) override; virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch, nsTArray* aPlugins, uint32_t* aNewPluginEpoch) override; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index b19f0d26a152..8029729eae4e 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -699,6 +699,11 @@ parent: */ sync ConnectPluginBridge(uint32_t aPluginId) returns (nsresult rv); + /** + * Return the current blocklist state for a particular plugin. + */ + sync GetBlocklistState(uint32_t aPluginId) returns (uint32_t aState); + /** * This call returns the set of plugins loaded in the chrome * process. However, in many cases this set will not have changed since the diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index ac9854448c77..f94eaed8d3ac 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -110,6 +110,8 @@ #include "nsExceptionHandler.h" #endif +#include "npapi.h" + using namespace mozilla; using mozilla::TimeStamp; using mozilla::plugins::PluginTag; @@ -1054,7 +1056,6 @@ nsPluginHost::GetBlocklistStateForType(const nsACString &aMimeType, aExcludeFlags, getter_AddRefs(tag)); NS_ENSURE_SUCCESS(rv, rv); - return tag->GetBlocklistState(aState); } diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h index 4966135320e4..b4eb527e8d65 100644 --- a/dom/plugins/base/nsPluginHost.h +++ b/dom/plugins/base/nsPluginHost.h @@ -11,7 +11,6 @@ #include "nsCOMPtr.h" #include "prlink.h" #include "prclist.h" -#include "npapi.h" #include "nsIPluginTag.h" #include "nsPluginsDir.h" #include "nsPluginDirServiceProvider.h" @@ -30,6 +29,7 @@ #include "nsCRT.h" #ifdef XP_WIN +#include #include "nsIWindowsRegKey.h" #endif @@ -52,6 +52,10 @@ class nsNPAPIPluginStreamListener; class nsIPluginInstanceOwner; class nsIInputStream; class nsIStreamListener; +#ifndef npapi_h_ +struct _NPP; +typedef _NPP* NPP; +#endif class nsInvalidPluginTag : public nsISupports { diff --git a/dom/plugins/base/nsPluginTags.cpp b/dom/plugins/base/nsPluginTags.cpp index 7e0be6170e67..fc3930b31b95 100644 --- a/dom/plugins/base/nsPluginTags.cpp +++ b/dom/plugins/base/nsPluginTags.cpp @@ -20,6 +20,7 @@ #include "mozilla/unused.h" #include #include "mozilla/dom/EncodingUtils.h" +#include "mozilla/dom/ContentChild.h" using mozilla::dom::EncodingUtils; using namespace mozilla; @@ -645,27 +646,33 @@ nsPluginTag::GetBlocklistState(uint32_t *aResult) return NS_OK; } - nsCOMPtr blocklist = - do_GetService("@mozilla.org/extensions/blocklist;1"); + if (XRE_GetProcessType() != GeckoProcessType_Default) { + *aResult = nsIBlocklistService::STATE_BLOCKED; + dom::ContentChild* cp = dom::ContentChild::GetSingleton(); + if (!cp->SendGetBlocklistState(mId, aResult)) { + return NS_OK; + } + } else { + nsCOMPtr blocklist = + do_GetService("@mozilla.org/extensions/blocklist;1"); - if (!blocklist) { - *aResult = nsIBlocklistService::STATE_NOT_BLOCKED; - return NS_OK; + if (!blocklist) { + *aResult = nsIBlocklistService::STATE_NOT_BLOCKED; + return NS_OK; + } + + // The EmptyString()s are so we use the currently running application + // and toolkit versions + if (NS_FAILED(blocklist->GetPluginBlocklistState(this, EmptyString(), + EmptyString(), aResult))) { + *aResult = nsIBlocklistService::STATE_NOT_BLOCKED; + return NS_OK; + } } - // The EmptyString()s are so we use the currently running application - // and toolkit versions - uint32_t state; - if (NS_FAILED(blocklist->GetPluginBlocklistState(this, EmptyString(), - EmptyString(), &state))) { - *aResult = nsIBlocklistService::STATE_NOT_BLOCKED; - return NS_OK; - } - - MOZ_ASSERT(state <= UINT16_MAX); - mCachedBlocklistState = (uint16_t) state; + MOZ_ASSERT(*aResult <= UINT16_MAX); + mCachedBlocklistState = (uint16_t) *aResult; mCachedBlocklistStateValid = true; - *aResult = state; return NS_OK; } From 167ae6301c40c4977b08109241001e52a9dfc2da Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 1 May 2015 10:07:19 -0500 Subject: [PATCH 04/10] Bug 1129040 - In the content process blocklist shim fail in all addon related calls. r=Mossop --- browser/installer/package-manifest.in | 1 + toolkit/mozapps/extensions/nsBlocklistService.js | 5 +++++ toolkit/mozapps/extensions/nsBlocklistServiceContent.js | 9 ++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 819797f85e26..de7d781d00bf 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -428,6 +428,7 @@ @RESPATH@/components/amInstallTrigger.js @RESPATH@/components/amWebInstallListener.js @RESPATH@/components/nsBlocklistService.js +@RESPATH@/components/nsBlocklistServiceContent.js #ifdef MOZ_UPDATER @RESPATH@/components/nsUpdateService.manifest @RESPATH@/components/nsUpdateService.js diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js index cbcfb4e989ab..8c2a9565b1b4 100644 --- a/toolkit/mozapps/extensions/nsBlocklistService.js +++ b/toolkit/mozapps/extensions/nsBlocklistService.js @@ -299,6 +299,7 @@ function Blocklist() { this.wrappedJSObject = this; // requests from child processes come in here, see receiveMessage. Services.ppmm.addMessageListener("Blocklist:getPluginBlocklistState", this); + Services.ppmm.addMessageListener("Blocklist:content-blocklist-updated", this); } Blocklist.prototype = { @@ -323,6 +324,7 @@ Blocklist.prototype = { shutdown: function () { Services.obs.removeObserver(this, "xpcom-shutdown"); Services.ppmm.removeMessageListener("Blocklist:getPluginBlocklistState", this); + Services.ppmm.removeMessageListener("Blocklist:content-blocklist-updated", this); gPref.removeObserver("extensions.blocklist.", this); gPref.removeObserver(PREF_EM_LOGGING_ENABLED, this); }, @@ -363,6 +365,9 @@ Blocklist.prototype = { return this.getPluginBlocklistState(aMsg.data.addonData, aMsg.data.appVersion, aMsg.data.toolkitVersion); + case "Blocklist:content-blocklist-updated": + Services.obs.notifyObservers(null, "content-blocklist-updated", null); + break; default: throw new Error("Unknown blocklist message received from content: " + aMsg.name); } diff --git a/toolkit/mozapps/extensions/nsBlocklistServiceContent.js b/toolkit/mozapps/extensions/nsBlocklistServiceContent.js index bb24c61008f2..b200c382d6f2 100644 --- a/toolkit/mozapps/extensions/nsBlocklistServiceContent.js +++ b/toolkit/mozapps/extensions/nsBlocklistServiceContent.js @@ -27,7 +27,8 @@ function Blocklist() { Blocklist.prototype = { classID: Components.ID("{e0a106ed-6ad4-47a4-b6af-2f1c8aa4712d}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIBlocklistService]), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsIBlocklistService]), init: function () { Services.cpmm.addMessageListener("Blocklist:blocklistInvalidated", this); @@ -52,6 +53,7 @@ Blocklist.prototype = { switch (aMsg.name) { case "Blocklist:blocklistInvalidated": Services.obs.notifyObservers(null, "blocklist-updated", null); + Services.cpmm.sendAsyncMessage("Blocklist:content-blocklist-updated"); break; default: throw new Error("Unknown blocklist message received from content: " + aMsg.name); @@ -79,13 +81,14 @@ Blocklist.prototype = { // only calls getPluginBlocklistState. isAddonBlocklisted: function (aAddon, aAppVersion, aToolkitVersion) { - throw new Error(kMissingAPIMessage); + return true; }, getAddonBlocklistState: function (aAddon, aAppVersion, aToolkitVersion) { - throw new Error(kMissingAPIMessage); + return Components.interfaces.nsIBlocklistService.STATE_BLOCKED; }, + // There are a few callers in layout that rely on this. getPluginBlocklistState: function (aPluginTag, aAppVersion, aToolkitVersion) { return Services.cpmm.sendSyncMessage("Blocklist:getPluginBlocklistState", { addonData: this.flattenObject(aPluginTag), From d9a767500528649bdd5f4a4153527debd4c28a74 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 1 May 2015 10:07:19 -0500 Subject: [PATCH 05/10] Bug 1129040 - Query the chrome process blocklist service prior to instantiating plugins in the content process. r=billm --- dom/base/nsObjectLoadingContent.cpp | 5 +++-- dom/plugins/base/nsPluginHost.cpp | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index c89456ed27ea..838ee5771445 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -3258,8 +3258,9 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp } // Before we check permissions, get the blocklist state of this plugin to set - // the fallback reason correctly. - uint32_t blocklistState = nsIBlocklistService::STATE_NOT_BLOCKED; + // the fallback reason correctly. In the content process this will involve + // an ipc call to chrome. + uint32_t blocklistState = nsIBlocklistService::STATE_BLOCKED; pluginHost->GetBlocklistStateForType(mContentType, nsPluginHost::eExcludeNone, &blocklistState); diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index f94eaed8d3ac..54cc3b13adc8 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -1276,6 +1276,13 @@ nsPluginHost::GetPluginForContentProcess(uint32_t aPluginId, nsNPAPIPlugin** aPl nsPluginTag* pluginTag = PluginWithId(aPluginId); if (pluginTag) { + // When setting up a bridge, double check with chrome to see if this plugin + // is blocked hard. Note this does not protect against vulnerable plugins + // that the user has explicitly allowed. :( + if (pluginTag->IsBlocklisted()) { + return NS_ERROR_PLUGIN_BLOCKLISTED; + } + nsresult rv = EnsurePluginLoaded(pluginTag); if (NS_FAILED(rv)) { return rv; From c67fc63e8ae26ff2cd0a835a36a2f5d21003dade Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 1 May 2015 10:07:20 -0500 Subject: [PATCH 06/10] Bug 1129040 - Update browser/base/content/test/plugins and enable for e10s. r=mconley --- .../content/test/plugins/blocklist_proxy.js | 78 ++ browser/base/content/test/plugins/browser.ini | 37 +- .../test/plugins/browser_CTP_context_menu.js | 151 +-- .../plugins/browser_CTP_crashreporting.js | 72 +- .../test/plugins/browser_CTP_data_urls.js | 361 +++--- .../test/plugins/browser_CTP_drag_drop.js | 134 +- .../test/plugins/browser_CTP_hide_overlay.js | 104 +- .../test/plugins/browser_CTP_iframe.js | 124 +- .../test/plugins/browser_CTP_multi_allow.js | 127 +- .../test/plugins/browser_CTP_nonplugins.js | 136 +- .../plugins/browser_CTP_notificationBar.js | 271 ++-- .../plugins/browser_CTP_outsideScrollArea.js | 201 ++- .../plugins/browser_CTP_remove_navigate.js | 79 +- .../test/plugins/browser_CTP_resize.js | 196 +-- .../content/test/plugins/browser_CTP_zoom.js | 99 +- .../content/test/plugins/browser_blocking.js | 360 ++++++ .../test/plugins/browser_blocklist_content.js | 108 ++ .../content/test/plugins/browser_bug743421.js | 193 +-- .../content/test/plugins/browser_bug744745.js | 82 +- .../content/test/plugins/browser_bug787619.js | 78 +- .../content/test/plugins/browser_bug797677.js | 62 +- .../content/test/plugins/browser_bug812562.js | 143 +-- .../content/test/plugins/browser_bug818118.js | 57 +- .../content/test/plugins/browser_bug820497.js | 104 +- .../test/plugins/browser_clearplugindata.html | 2 - .../test/plugins/browser_clearplugindata.js | 152 ++- .../browser_clearplugindata_noage.html | 2 - .../browser_globalplugin_crashinfobar.js | 4 - .../browser_pluginCrashCommentAndURL.js | 5 - .../test/plugins/browser_plugin_infolink.js | 77 ++ .../test/plugins/browser_plugin_reloading.js | 85 ++ .../plugins/browser_pluginnotification.js | 1129 ++++++----------- .../test/plugins/browser_pluginplaypreview.js | 4 - .../plugins/browser_pluginplaypreview2.js | 4 - .../plugins/browser_pluginplaypreview3.js | 4 - .../browser_plugins_added_dynamically.js | 243 ++-- browser/base/content/test/plugins/head.js | 360 ++++-- .../test/plugins/plugin_add_dynamically.html | 7 +- .../content/test/plugins/plugin_both.html | 6 +- .../plugins/plugin_hidden_to_visible.html | 4 +- .../test/plugins/plugin_syncRemoved.html | 3 +- .../content/test/plugins/plugin_test.html | 6 +- .../content/test/plugins/plugin_test3.html | 6 +- .../content/test/plugins/plugin_unknown.html | 6 +- 44 files changed, 2914 insertions(+), 2552 deletions(-) create mode 100644 browser/base/content/test/plugins/blocklist_proxy.js create mode 100644 browser/base/content/test/plugins/browser_blocking.js create mode 100644 browser/base/content/test/plugins/browser_blocklist_content.js create mode 100644 browser/base/content/test/plugins/browser_plugin_infolink.js create mode 100644 browser/base/content/test/plugins/browser_plugin_reloading.js diff --git a/browser/base/content/test/plugins/blocklist_proxy.js b/browser/base/content/test/plugins/blocklist_proxy.js new file mode 100644 index 000000000000..f583f3b82cd0 --- /dev/null +++ b/browser/base/content/test/plugins/blocklist_proxy.js @@ -0,0 +1,78 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; +const Cm = Components.manager; + +const kBlocklistServiceUUID = "{66354bc9-7ed1-4692-ae1d-8da97d6b205e}"; +const kBlocklistServiceContractID = "@mozilla.org/extensions/blocklist;1"; +const kBlocklistServiceFactory = Cm.getClassObject(Cc[kBlocklistServiceContractID], Ci.nsIFactory); + +Cu.import('resource://gre/modules/XPCOMUtils.jsm'); + +/* + * A lightweight blocklist proxy for the testing purposes. + */ +let BlocklistProxy = { + _uuid: null, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsIBlocklistService, + Ci.nsITimerCallback]), + + init: function() { + if (!this._uuid) { + this._uuid = + Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator) + .generateUUID(); + Cm.nsIComponentRegistrar.registerFactory(this._uuid, "", + "@mozilla.org/extensions/blocklist;1", + this); + } + }, + + uninit: function() { + if (this._uuid) { + Cm.nsIComponentRegistrar.unregisterFactory(this._uuid, this); + Cm.nsIComponentRegistrar.registerFactory(Components.ID(kBlocklistServiceUUID), + "Blocklist Service", + "@mozilla.org/extensions/blocklist;1", + kBlocklistServiceFactory); + this._uuid = null; + } + }, + + notify: function (aTimer) { + }, + + observe: function (aSubject, aTopic, aData) { + }, + + isAddonBlocklisted: function (aAddon, aAppVersion, aToolkitVersion) { + return false; + }, + + getAddonBlocklistState: function (aAddon, aAppVersion, aToolkitVersion) { + return 0; // STATE_NOT_BLOCKED + }, + + getPluginBlocklistState: function (aPluginTag, aAppVersion, aToolkitVersion) { + return 0; // STATE_NOT_BLOCKED + }, + + getAddonBlocklistURL: function (aAddon, aAppVersion, aToolkitVersion) { + return ""; + }, + + getPluginBlocklistURL: function (aPluginTag) { + return ""; + }, + + getPluginInfoURL: function (aPluginTag) { + return ""; + }, +} + +BlocklistProxy.init(); +addEventListener("unload", () => { + BlocklistProxy.uninit(); +}); diff --git a/browser/base/content/test/plugins/browser.ini b/browser/base/content/test/plugins/browser.ini index 8e0b2b2f33d1..b28dec5edfff 100644 --- a/browser/base/content/test/plugins/browser.ini +++ b/browser/base/content/test/plugins/browser.ini @@ -1,12 +1,7 @@ [DEFAULT] -# These tests all fail with e10s enabled. -# * Bug 899347 - no e10s click-to-play support -# * Bug 921916 - no plugin events -# * Bug XXXXX - no plugins in content processes ("Error: You cannot use the AddonManager in child processes!") -# * Bug 866413 - PageInfo doesn't work in e10s [browser_pageInfo_plugins.js] -# * Bug 921957 - remote webprogress doesn't supply originalURI attribute on the request object [browser_clearplugindata.js] -skip-if = buildapp == "mulet" || e10s +skip-if = buildapp == "mulet" support-files = + blocklist_proxy.js blockNoPlugins.xml blockPluginHard.xml blockPluginInfoURL.xml @@ -53,12 +48,14 @@ support-files = [browser_bug818118.js] [browser_bug820497.js] [browser_clearplugindata.js] +skip-if = e10s # bug 1149253 [browser_CTP_context_menu.js] -skip-if = toolkit == "gtk2" || toolkit == "gtk3" # browser_CTP_context_menu.js fails intermittently on Linux (bug 909342) +skip-if = toolkit == "gtk2" || toolkit == "gtk3" # fails intermittently on Linux (bug 909342) [browser_CTP_crashreporting.js] skip-if = !crashreporter [browser_CTP_data_urls.js] [browser_CTP_drag_drop.js] +skip-if = e10s # misc. issues, bug 1156871 [browser_CTP_hide_overlay.js] [browser_CTP_iframe.js] skip-if = os == 'linux' || os == 'mac' # Bug 984821 @@ -69,14 +66,26 @@ skip-if = os == 'linux' || os == 'mac' # Bug 984821 [browser_CTP_remove_navigate.js] [browser_CTP_resize.js] [browser_CTP_zoom.js] -[browser_globalplugin_crashinfobar.js] -[browser_pageInfo_plugins.js] +[browser_blocking.js] +[browser_plugins_added_dynamically.js] [browser_pluginnotification.js] -[browser_pluginplaypreview.js] -[browser_pluginplaypreview2.js] -[browser_pluginplaypreview3.js] +[browser_plugin_infolink.js] +skip-if = e10s # bug 1160166 +[browser_plugin_reloading.js] +[browser_blocklist_content.js] +skip-if = !e10s +[browser_globalplugin_crashinfobar.js] +skip-if = !crashreporter [browser_pluginCrashCommentAndURL.js] skip-if = !crashreporter -[browser_plugins_added_dynamically.js] +[browser_pageInfo_plugins.js] +skip-if = e10s # Bug 866413 +[browser_pluginplaypreview.js] +skip-if = e10s # bug 1148827 +[browser_pluginplaypreview2.js] +skip-if = e10s # bug 1148827 +[browser_pluginplaypreview3.js] +skip-if = e10s # bug 1148827 [browser_pluginCrashReportNonDeterminism.js] skip-if = !crashreporter || os == 'linux' # Bug 1152811 + diff --git a/browser/base/content/test/plugins/browser_CTP_context_menu.js b/browser/base/content/test/plugins/browser_CTP_context_menu.js index 1f4d4e780590..ca4f270a28cf 100644 --- a/browser/base/content/test/plugins/browser_CTP_context_menu.js +++ b/browser/base/content/test/plugins/browser_CTP_context_menu.js @@ -1,116 +1,69 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); }); - Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - - prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_test.html"); -} - -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} - -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} - -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} - -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} +}); // Test that the activate action in content menus for CTP plugins works -function test1() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); +add_task(function* () { + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + + gBrowser.selectedTab = gBrowser.addTab(); + + Services.prefs.setBoolPref("plugins.click_to_play", true); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + let bindingPromise = waitForEvent(gBrowser.selectedBrowser, "PluginBindingAttached", null, true, true); + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); + yield bindingPromise; + + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); ok(popupNotification, "Test 1, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 1, Plugin should not be activated"); + // check plugin state + let pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser); + ok(!pluginInfo.activated, "plugin should not be activated"); + + // Display a context menu on the test plugin so we can test + // activation menu options. + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("contextmenu", left, top, 2, 1, 0); + }); - // When the popupshown DOM event is fired, the actual showing of the popup - // may still be pending. Clear the event loop before continuing so that - // subsequently-opened popups aren't cancelled by accident. - let goToNext = function(aEvent) { - window.document.removeEventListener("popupshown", goToNext, false); - executeSoon(function() { - test2(); - aEvent.target.hidePopup(); - }); - }; - window.document.addEventListener("popupshown", goToNext, false); - EventUtils.synthesizeMouseAtCenter(plugin, - { type: "contextmenu", button: 2 }, - gTestBrowser.contentWindow); -} + popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); + ok(popupNotification, "Should have a click-to-play notification"); + ok(popupNotification.dismissed, "notification should be dismissed"); -function test2() { - let activate = window.document.getElementById("context-ctp-play"); - ok(activate, "Test 2, Should have a context menu entry for activating the plugin"); + // fixes a occasional test timeout on win7 opt + yield promiseForCondition(() => document.getElementById("context-ctp-play")); - let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(notification, "Test 2, Should have a click-to-play notification"); - ok(notification.dismissed, "Test 2, notification should be dismissed"); + let actMenuItem = document.getElementById("context-ctp-play"); + ok(actMenuItem, "Should have a context menu entry for activating the plugin"); - // Trigger the click-to-play popup - activate.doCommand(); + // Activate the plugin via the context menu + EventUtils.synthesizeMouseAtCenter(actMenuItem, {}); - waitForCondition(() => !notification.dismissed, - test3, "Test 2, waited too long for context activation"); -} + yield promiseForCondition(() => !PopupNotifications.panel.dismissed && PopupNotifications.panel.firstChild); -function test3() { // Activate the plugin PopupNotifications.panel.firstChild._primaryButton.click(); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - waitForCondition(() => objLoadingContent.activated, test4, "Waited too long for plugin to activate"); -} - -function test4() { - finishTest(); -} + // check plugin state + pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser); + ok(pluginInfo.activated, "plugin should not be activated"); +}); diff --git a/browser/base/content/test/plugins/browser_CTP_crashreporting.js b/browser/base/content/test/plugins/browser_CTP_crashreporting.js index 680d1717104f..f0384881f426 100644 --- a/browser/base/content/test/plugins/browser_CTP_crashreporting.js +++ b/browser/base/content/test/plugins/browser_CTP_crashreporting.js @@ -1,10 +1,8 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs"; -const PLUGIN_PAGE = getRootDirectory(gTestPath) + "plugin_big.html"; -const PLUGIN_SMALL_PAGE = getRootDirectory(gTestPath) + "plugin_small.html"; +const PLUGIN_PAGE = gTestRoot + "plugin_big.html"; +const PLUGIN_SMALL_PAGE = gTestRoot + "plugin_small.html"; /** * Takes an nsIPropertyBag and converts it into a JavaScript Object. It @@ -30,14 +28,8 @@ function convertPropertyBag(aBag) { return result; } -function promisePopupNotificationShown(notificationID) { - return new Promise((resolve) => { - waitForNotificationShown(notificationID, resolve); - }); -} - add_task(function* setup() { - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin // crash reports. This test needs them enabled. The test also needs a mock @@ -51,9 +43,17 @@ add_task(function* setup() { env.set("MOZ_CRASHREPORTER_NO_REPORT", ""); env.set("MOZ_CRASHREPORTER_URL", SERVER_URL); + Services.prefs.setBoolPref("plugins.click_to_play", true); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + registerCleanupFunction(function cleanUp() { + clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport); env.set("MOZ_CRASHREPORTER_URL", serverURL); + Services.prefs.clearUserPref("plugins.click_to_play"); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + window.focus(); }); }); @@ -66,20 +66,15 @@ add_task(function*() { gBrowser, url: PLUGIN_PAGE, }, function* (browser) { - let activated = yield ContentTask.spawn(browser, null, function*() { - let plugin = content.document.getElementById("test"); - return plugin.QueryInterface(Ci.nsIObjectLoadingContent).activated; - }); - ok(!activated, "Plugin should not be activated"); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(browser); - // Open up the click-to-play notification popup... - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", - browser); - ok(popupNotification, "Should have a click-to-play notification"); + let pluginInfo = yield promiseForPluginInfo("test", browser); + ok(!pluginInfo.activated, "Plugin should not be activated"); - yield promisePopupNotificationShown(popupNotification); - - // The primary button in the popup should activate the plugin. + // Simulate clicking the "Allow Always" button. + let notification = PopupNotifications.getNotification("click-to-play-plugins", browser); + yield promiseForNotificationShown(notification, browser); PopupNotifications.panel.firstChild._primaryButton.click(); // Prepare a crash report topic observer that only returns when @@ -99,8 +94,9 @@ add_task(function*() { }, "Waited too long for plugin to activate."); try { - plugin.crash(); - } catch(e) {} + Components.utils.waiveXrays(plugin).crash(); + } catch(e) { + } let doc = plugin.ownerDocument; @@ -177,21 +173,11 @@ add_task(function*() { gBrowser, url: PLUGIN_SMALL_PAGE, }, function* (browser) { - let activated = yield ContentTask.spawn(browser, null, function*() { - let plugin = content.document.getElementById("test"); - return plugin.QueryInterface(Ci.nsIObjectLoadingContent).activated; - }); - ok(!activated, "Plugin should not be activated"); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(browser); - // Open up the click-to-play notification popup... - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", - browser); - ok(popupNotification, "Should have a click-to-play notification"); - - yield promisePopupNotificationShown(popupNotification); - - // The primary button in the popup should activate the plugin. - PopupNotifications.panel.firstChild._primaryButton.click(); + let pluginInfo = yield promiseForPluginInfo("test", browser); + ok(pluginInfo.activated, "Plugin should be activated from previous test"); // Prepare a crash report topic observer that only returns when // the crash report has been successfully sent. @@ -210,7 +196,7 @@ add_task(function*() { }, "Waited too long for plugin to activate."); try { - plugin.crash(); + Components.utils.waiveXrays(plugin).crash(); } catch(e) {} }); @@ -244,4 +230,4 @@ add_task(function*() { is(crashData.extra.PluginContentURL, undefined, "URL should be absent from extra data when opt-in not checked"); }); -}); \ No newline at end of file +}); diff --git a/browser/base/content/test/plugins/browser_CTP_data_urls.js b/browser/base/content/test/plugins/browser_CTP_data_urls.js index 64147dace2e7..d5279c10d59b 100644 --- a/browser/base/content/test/plugins/browser_CTP_data_urls.js +++ b/browser/base/content/test/plugins/browser_CTP_data_urls.js @@ -1,212 +1,255 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); +let gTestBrowser = null; -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; }); - Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - var newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; + gBrowser.selectedTab = gBrowser.addTab(); gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); - - prepareTest(test1a, gHttpTestRoot + "plugin_data_url.html"); -} - -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} - -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} - -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} - -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} +}); // Test that the click-to-play doorhanger still works when navigating to data URLs -function test1a() { +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_data_url.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); ok(popupNotification, "Test 1a, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated"); + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 1a, plugin should not be activated"); - gNextTest = runAfterPluginBindingAttached(test1b); - gTestBrowser.contentDocument.getElementById("data-link-1").click(); -} + let loadPromise = promiseTabLoadEvent(gBrowser.selectedTab); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + // navigate forward to a page with 'test' in it + content.document.getElementById("data-link-1").click(); + }); + yield loadPromise; -function test1b() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); ok(popupNotification, "Test 1b, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated"); + pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 1b, plugin should not be activated"); + + let promise = promisePopupNotification("click-to-play-plugins"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); + yield promise; // Simulate clicking the "Allow Always" button. - waitForNotificationShown(popupNotification, function() { - PopupNotifications.panel.firstChild._primaryButton.click(); + let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed && + PopupNotifications.panel.firstChild; + yield promiseForCondition(condition); + PopupNotifications.panel.firstChild._primaryButton.click(); - let condition = function() objLoadingContent.activated; - waitForCondition(condition, test1c, "Test 1b, Waited too long for plugin to activate"); - }); -} + // check plugin state + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 1b, plugin should be activated"); +}); -function test1c() { +// Test that the click-to-play notification doesn't break when navigating +// to data URLs with multiple plugins. +add_task(function* () { + // We click activated above clearAllPluginPermissions(); - prepareTest(runAfterPluginBindingAttached(test2a), gHttpTestRoot + "plugin_data_url.html"); -} -// Test that the click-to-play notification doesn't break when navigating to data URLs with multiple plugins -function test2a() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 2a, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 2a, Plugin should not be activated"); + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_data_url.html"); - gNextTest = runAfterPluginBindingAttached(test2b); - gTestBrowser.contentDocument.getElementById("data-link-2").click(); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -function test2b() { let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 2a, Should have a click-to-play notification"); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 2a, plugin should not be activated"); + + let loadPromise = promiseTabLoadEvent(gBrowser.selectedTab); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + // navigate forward to a page with 'test1' & 'test2' in it + content.document.getElementById("data-link-2").click(); + }); + yield loadPromise; + + // Work around for delayed PluginBindingAttached + yield ContentTask.spawn(gTestBrowser, {}, function* () { + content.document.getElementById("test1").clientTop; + content.document.getElementById("test2").clientTop; + }); + + pluginInfo = yield promiseForPluginInfo("test1"); + ok(!pluginInfo.activated, "Test 2a, test1 should not be activated"); + pluginInfo = yield promiseForPluginInfo("test2"); + ok(!pluginInfo.activated, "Test 2a, test2 should not be activated"); + + notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); ok(notification, "Test 2b, Should have a click-to-play notification"); + yield promiseForNotificationShown(notification); + // Simulate choosing "Allow now" for the test plugin - waitForNotificationShown(notification, function() { - is(notification.options.pluginData.size, 2, "Test 2b, Should have two types of plugin in the notification"); + is(notification.options.pluginData.size, 2, "Test 2b, Should have two types of plugin in the notification"); - var centerAction = null; - for (var action of notification.options.pluginData.values()) { - if (action.pluginName == "Test") { - centerAction = action; - break; - } + let centerAction = null; + for (let action of notification.options.pluginData.values()) { + if (action.pluginName == "Test") { + centerAction = action; + break; } - ok(centerAction, "Test 2b, found center action for the Test plugin"); + } + ok(centerAction, "Test 2b, found center action for the Test plugin"); - var centerItem = null; - for (var item of PopupNotifications.panel.firstChild.childNodes) { - is(item.value, "block", "Test 2b, all plugins should start out blocked"); - if (item.action == centerAction) { - centerItem = item; - break; - } + let centerItem = null; + for (let item of PopupNotifications.panel.firstChild.childNodes) { + is(item.value, "block", "Test 2b, all plugins should start out blocked"); + if (item.action == centerAction) { + centerItem = item; + break; } - ok(centerItem, "Test 2b, found center item for the Test plugin"); + } + ok(centerItem, "Test 2b, found center item for the Test plugin"); - // "click" the button to activate the Test plugin - centerItem.value = "allownow"; - PopupNotifications.panel.firstChild._primaryButton.click(); + // "click" the button to activate the Test plugin + centerItem.value = "allownow"; + PopupNotifications.panel.firstChild._primaryButton.click(); - let plugin = gTestBrowser.contentDocument.getElementById("test1"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - let condition = function() objLoadingContent.activated; - waitForCondition(condition, test2c, "Test 2b, Waited too long for plugin to activate"); - }); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -function test2c() { - let plugin = gTestBrowser.contentDocument.getElementById("test1"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 2c, Plugin should be activated"); + // check plugin state + pluginInfo = yield promiseForPluginInfo("test1"); + ok(pluginInfo.activated, "Test 2b, plugin should be activated"); +}); +add_task(function* () { + // We click activated above clearAllPluginPermissions(); - prepareTest(runAfterPluginBindingAttached(test3a), gHttpTestRoot + "plugin_data_url.html"); -} + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_data_url.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); +}); // Test that when navigating to a data url, the plugin permission is inherited -function test3a() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 3a, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 3a, Plugin should not be activated"); +add_task(function* () { + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 3a, Should have a click-to-play notification"); + + // check plugin state + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 3a, plugin should not be activated"); + + let promise = promisePopupNotification("click-to-play-plugins"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); + yield promise; // Simulate clicking the "Allow Always" button. - waitForNotificationShown(popupNotification, function() { - PopupNotifications.panel.firstChild._primaryButton.click(); + let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed && + PopupNotifications.panel.firstChild; + yield promiseForCondition(condition); + PopupNotifications.panel.firstChild._primaryButton.click(); - let condition = function() objLoadingContent.activated; - waitForCondition(condition, test3b, "Test 3a, Waited too long for plugin to activate"); + // check plugin state + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 3a, plugin should be activated"); + + let loadPromise = promiseTabLoadEvent(gBrowser.selectedTab); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + // navigate forward to a page with 'test' in it + content.document.getElementById("data-link-1").click(); }); -} + yield loadPromise; -function test3b() { - gNextTest = test3c; - gTestBrowser.contentDocument.getElementById("data-link-1").click(); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -function test3c() { - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 3c, Plugin should be activated"); + // check plugin state + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 3b, plugin should be activated"); clearAllPluginPermissions(); - prepareTest(runAfterPluginBindingAttached(test4b), - 'data:text/html,'); -} +}); -// Test that the click-to-play doorhanger still works when directly navigating to data URLs -function test4a() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 4a, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 4a, Plugin should not be activated"); +// Test that the click-to-play doorhanger still works +// when directly navigating to data URLs. +// Fails, bug XXX. Plugins plus a data url don't fire a load event. +/* +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, + "data:text/html,Hi!"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 4a, Should have a click-to-play notification"); + + // check plugin state + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 4a, plugin should not be activated"); + + let promise = promisePopupNotification("click-to-play-plugins"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); + yield promise; // Simulate clicking the "Allow Always" button. - waitForNotificationShown(popupNotification, function() { - PopupNotifications.panel.firstChild._primaryButton.click(); + let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed && + PopupNotifications.panel.firstChild; + yield promiseForCondition(condition); + PopupNotifications.panel.firstChild._primaryButton.click(); - let condition = function() objLoadingContent.activated; - waitForCondition(condition, test4b, "Test 4a, Waited too long for plugin to activate"); - }); -} - -function test4b() { - clearAllPluginPermissions(); - finishTest(); -} + // check plugin state + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 4a, plugin should be activated"); +}); +*/ \ No newline at end of file diff --git a/browser/base/content/test/plugins/browser_CTP_drag_drop.js b/browser/base/content/test/plugins/browser_CTP_drag_drop.js index 66b7de28aa3a..96d12f286b19 100644 --- a/browser/base/content/test/plugins/browser_CTP_drag_drop.js +++ b/browser/base/content/test/plugins/browser_CTP_drag_drop.js @@ -1,102 +1,96 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -let gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); - -let gNextTest = null; +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); let gNewWindow = null; -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); Services.prefs.clearUserPref("plugins.click_to_play"); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gNewWindow.close(); + gNewWindow = null; + window.focus(); }); +}); + +add_task(function* () { Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); gBrowser.selectedTab = gBrowser.addTab(); - gBrowser.selectedBrowser.addEventListener("PluginBindingAttached", handleEvent, true, true); - gNextTest = part1; - gBrowser.selectedBrowser.contentDocument.location = gHttpTestRoot + "plugin_test.html"; -} -function handleEvent() { - gNextTest(); -} + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); -function part1() { - gBrowser.selectedBrowser.removeEventListener("PluginBindingAttached", handleEvent); - waitForNotificationPopup("click-to-play-plugins", gBrowser.selectedBrowser, () => { - gNextTest = part2; - gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab); - gNewWindow.addEventListener("load", handleEvent, true); - }); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); -function part2() { - gNewWindow.removeEventListener("load", handleEvent); - let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser); - waitForCondition(condition, part3, "Waited too long for click-to-play notification"); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); + + yield promisePopupNotification("click-to-play-plugins"); +}); + +add_task(function* () { + gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab); + + // XXX technically can't load fire before we get this call??? + yield waitForEvent(gNewWindow, "load", null, true); + + yield promisePopupNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser); -function part3() { ok(PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser), "Should have a click-to-play notification in the tab in the new window"); ok(!PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should not have a click-to-play notification in the old window now"); +}); +add_task(function* () { gBrowser.selectedTab = gBrowser.addTab(); gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, gNewWindow.gBrowser.selectedTab); - let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); - waitForCondition(condition, part4, "Waited too long for click-to-play notification"); -} -function part4() { + yield promisePopupNotification("click-to-play-plugins", gBrowser.selectedBrowser); + ok(PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should have a click-to-play notification in the initial tab again"); - gBrowser.selectedBrowser.addEventListener("PluginBindingAttached", handleEvent, true, true); - gNextTest = part5; - gBrowser.selectedBrowser.contentDocument.location = gHttpTestRoot + "plugin_test.html"; -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); +}); -function part5() { - gBrowser.selectedBrowser.removeEventListener("PluginBindingAttached", handleEvent); - waitForNotificationPopup("click-to-play-plugins", gBrowser.selectedBrowser, () => { - gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab); - waitForFocus(part6, gNewWindow); - }); -} +add_task(function* () { + yield promisePopupNotification("click-to-play-plugins"); -function part6() { - let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser); - waitForCondition(condition, part7, "Waited too long for click-to-play notification"); -} + gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab); -function part7() { + yield promiseWaitForFocus(gNewWindow); + + yield promisePopupNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser); +}); + +add_task(function* () { ok(PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser), "Should have a click-to-play notification in the tab in the new window"); ok(!PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should not have a click-to-play notification in the old window now"); - let plugin = gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "plugin should not be activated"); + let pluginInfo = yield promiseForPluginInfo("test", gNewWindow.gBrowser.selectedBrowser); + ok(!pluginInfo.activated, "plugin should not be activated"); + + yield ContentTask.spawn(gNewWindow.gBrowser.selectedBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); - EventUtils.synthesizeMouseAtCenter(plugin, {}, gNewWindow.gBrowser.selectedBrowser.contentWindow); let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser).dismissed && gNewWindow.PopupNotifications.panel.firstChild; - waitForCondition(condition, part8, "waited too long for plugin to activate"); -} + yield promiseForCondition(condition); +}); -function part8() { +add_task(function* () { // Click the activate button on doorhanger to make sure it works gNewWindow.PopupNotifications.panel.firstChild._primaryButton.click(); - let plugin = gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - waitForCondition(() => objLoadingContent.activated, shutdown, "plugin should be activated now"); -} - -function shutdown() { - gNewWindow.close(); - gNewWindow = null; - finish(); -} + let pluginInfo = yield promiseForPluginInfo("test", gNewWindow.gBrowser.selectedBrowser); + ok(pluginInfo.activated, "plugin should be activated"); +}); diff --git a/browser/base/content/test/plugins/browser_CTP_hide_overlay.js b/browser/base/content/test/plugins/browser_CTP_hide_overlay.js index 7b4fcb7e3b79..9c0d0fba598b 100644 --- a/browser/base/content/test/plugins/browser_CTP_hide_overlay.js +++ b/browser/base/content/test/plugins/browser_CTP_hide_overlay.js @@ -1,76 +1,54 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); }); +}); + +add_task(function* () { Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); + gBrowser.selectedTab = gBrowser.addTab(); Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_DISABLED); - prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_test.html"); -} + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} + // Tests that the overlay can be hidded for disabled plugins using the close icon. + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon") + let bounds = closeIcon.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} - -// Tests that the overlay can be hidded for disabled plugins using the close icon. -function test1() { - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - ok(plugin, "Test 1, Found plugin in page"); - var overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay.classList.contains("visible"), "Test 1, Plugin overlay should exist, not be hidden"); - var closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon") - EventUtils.synthesizeMouseAtCenter(closeIcon, {}, gTestBrowser.contentWindow); - var condition = function() !overlay.classList.contains("visible"); - waitForCondition(condition, finishTest, "Test 1, Waited too long for the overlay to become invisible."); -} + let overlayIsVisible = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return plugin && overlay.classList.contains("visible"); + }); + ok(!overlayIsVisible, "overlay should be hidden."); +}); diff --git a/browser/base/content/test/plugins/browser_CTP_iframe.js b/browser/base/content/test/plugins/browser_CTP_iframe.js index f459a3fcef2e..1ab6f96abbda 100644 --- a/browser/base/content/test/plugins/browser_CTP_iframe.js +++ b/browser/base/content/test/plugins/browser_CTP_iframe.js @@ -1,104 +1,54 @@ let rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); -let gTestBrowser = null; -let gNextTest = null; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); }); +}); + +add_task(function* () { Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); + gBrowser.selectedTab = gBrowser.addTab(); Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); - prepareTest(delayTest(runAfterPluginBindingAttached(test1)), gHttpTestRoot + "plugin_iframe.html"); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_iframe.html"); -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + // Tests that the overlays are visible and actionable if the plugin is in an iframe. -function pageLoad() { - gNextTest(); -} - -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} - -// Delay executing a test for one load event to wait for frame loads. -function delayTest(nextTest) { - return () => { - gNextTest = nextTest; - } -} - -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return () => { - let frame = gTestBrowser.contentDocument.getElementById("frame"); + let result = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let frame = content.document.getElementById("frame"); let doc = frame.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} - -// Tests that the overlays are visible and actionable if the plugin is in an iframe. -function test1() { - let frame = gTestBrowser.contentDocument.getElementById("frame"); - let doc = frame.contentDocument; - let plugin = doc.getElementById("test"); - ok(plugin, "Test 1, Found plugin in page"); - - waitForNotificationPopup("click-to-play-plugins", gTestBrowser, () => { + let plugin = doc.getElementById("test"); let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay.classList.contains("visible"), "Test 1, Plugin overlay should exist, not be hidden"); - let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon"); - - EventUtils.synthesizeMouseAtCenter(closeIcon, {}, frame.contentWindow); - let condition = () => !overlay.classList.contains("visible"); - waitForCondition(condition, test2, "Test 1, Waited too long for the overlay to become invisible."); + return plugin && overlay.classList.contains("visible"); }); -} + ok(result, "Test 1, Plugin overlay should exist, not be hidden"); -function test2() { - prepareTest(delayTest(runAfterPluginBindingAttached(test3)), gHttpTestRoot + "plugin_iframe.html"); -} + result = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let frame = content.document.getElementById("frame"); + let doc = frame.contentDocument; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon"); + let bounds = closeIcon.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = doc.defaultView.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + return overlay.classList.contains("visible"); + }); + ok(!result, "Test 1, Plugin overlay should exist, be hidden"); +}); -function test3() { - let frame = gTestBrowser.contentDocument.getElementById("frame"); - let doc = frame.contentDocument; - let plugin = doc.getElementById("test"); - ok(plugin, "Test 3, Found plugin in page"); - - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay.classList.contains("visible"), "Test 3, Plugin overlay should exist, not be hidden"); - - EventUtils.synthesizeMouseAtCenter(plugin, {}, frame.contentWindow); - let condition = () => PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - waitForCondition(condition, finishTest, "Test 3, Waited too long for the doorhanger to pop up."); -} diff --git a/browser/base/content/test/plugins/browser_CTP_multi_allow.js b/browser/base/content/test/plugins/browser_CTP_multi_allow.js index 40ce419e7412..ca42866ae085 100644 --- a/browser/base/content/test/plugins/browser_CTP_multi_allow.js +++ b/browser/base/content/test/plugins/browser_CTP_multi_allow.js @@ -1,83 +1,51 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); }); +}); + +add_task(function* () { Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - var newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); + gBrowser.selectedTab = gBrowser.addTab(); Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); - prepareTest(test1a, gHttpTestRoot + "plugin_two_types.html"); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html"); -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} + // Test that the click-to-play doorhanger for multiple plugins shows the correct + // state when re-opening without reloads or navigation. -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} + let pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser); + ok(!pluginInfo.activated, "plugin should be activated"); -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} - -// Test that the click-to-play doorhanger for multiple plugins shows the correct -// state when re-opening without reloads or navigation. - -function test1a() { - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("test"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test1a, Plugin should not be activated"); - - let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + let notification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); ok(notification, "Test 1a, Should have a click-to-play notification"); - notification.reshow(); + + yield promiseForNotificationShown(notification); is(notification.options.pluginData.size, 2, - "Test 1a, Should have two types of plugin in the notification"); + "Test 1a, Should have two types of plugin in the notification"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); + + is(PopupNotifications.panel.firstChild.childNodes.length, 2, "have child nodes"); let pluginItem = null; for (let item of PopupNotifications.panel.firstChild.childNodes) { @@ -86,21 +54,20 @@ function test1a() { pluginItem = item; } } - + // Choose "Allow now" for the test plugin pluginItem.value = "allownow"; PopupNotifications.panel.firstChild._primaryButton.click(); - waitForCondition(() => objLoadingContent.activated, test1b, - "Test 1a, Waited too long for plugin to activate"); -} + pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser); + ok(pluginInfo.activated, "plugin should be activated"); -function test1b() { - let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + notification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); ok(notification, "Test 1b, Should have a click-to-play notification"); - notification.reshow(); - let pluginItem = null; + yield promiseForNotificationShown(notification); + + pluginItem = null; for (let item of PopupNotifications.panel.firstChild.childNodes) { if (item.action.pluginName == "Test") { is(item.value, "allownow", "Test 1b, Test plugin should now be set to 'Allow now'"); @@ -114,17 +81,13 @@ function test1b() { pluginItem.value = "allowalways"; PopupNotifications.panel.firstChild._primaryButton.click(); - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("secondtestA"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - waitForCondition(() => objLoadingContent.activated, test1c, - "Test 1b, Waited too long for plugin to activate"); -} + pluginInfo = yield promiseForPluginInfo("secondtestA", gBrowser.selectedBrowser); + ok(pluginInfo.activated, "plugin should be activated"); -function test1c() { - let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + notification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); ok(notification, "Test 1c, Should have a click-to-play notification"); - notification.reshow(); + + yield promiseForNotificationShown(notification); for (let item of PopupNotifications.panel.firstChild.childNodes) { if (item.action.pluginName == "Test") { @@ -133,6 +96,4 @@ function test1c() { is(item.value, "allowalways", "Test 1c, Second Test plugin should be set to 'Allow always'"); } } - - finishTest(); -} +}); diff --git a/browser/base/content/test/plugins/browser_CTP_nonplugins.js b/browser/base/content/test/plugins/browser_CTP_nonplugins.js index 824606f00ca1..5b0bbc1eb0aa 100644 --- a/browser/base/content/test/plugins/browser_CTP_nonplugins.js +++ b/browser/base/content/test/plugins/browser_CTP_nonplugins.js @@ -1,114 +1,58 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); -var gRunNextTestAfterPluginRemoved = false; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); - gTestBrowser.removeEventListener("PluginRemoved", handlePluginRemoved, true, true); + gBrowser.removeCurrentTab(); + window.focus(); }); +}); + +add_task(function* () { + Services.prefs.setBoolPref("plugins.click_to_play", true); Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - var newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - gTestBrowser.addEventListener("PluginRemoved", handlePluginRemoved, true, true); + gBrowser.selectedTab = gBrowser.addTab(); - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_DISABLED, "Test Plug-in"); - prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_two_types.html"); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html"); -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} - -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} - -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} - -function handlePluginRemoved() { - if (gRunNextTestAfterPluginRemoved) { - executeSoon(gNextTest); - gRunNextTestAfterPluginRemoved = false; - } -} - -function runAfterPluginRemoved(func) { - gNextTest = func; - gRunNextTestAfterPluginRemoved = true; -} - -// Test that the click-to-play notification is not shown for non-plugin object elements - -function test1() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + // Test that the click-to-play notification is not shown for non-plugin object elements + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); ok(popupNotification, "Test 1, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("secondtestA"); - plugin.parentNode.removeChild(plugin); - plugin = gTestBrowser.contentDocument.getElementById("secondtestB"); - plugin.parentNode.removeChild(plugin); + let pluginRemovedPromise = waitForEvent(gBrowser.selectedBrowser, "PluginRemoved", null, true, true); + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let plugin = content.document.getElementById("secondtestA"); + plugin.parentNode.removeChild(plugin); + plugin = content.document.getElementById("secondtestB"); + plugin.parentNode.removeChild(plugin); - let image = gTestBrowser.contentDocument.createElement("object"); - image.type = "image/png"; - image.data = "moz.png"; - gTestBrowser.contentDocument.body.appendChild(image); + let image = content.document.createElement("object"); + image.type = "image/png"; + image.data = "moz.png"; + content.document.body.appendChild(image); + }); + yield pluginRemovedPromise; - runAfterPluginRemoved(test2); -} - -function test2() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); ok(popupNotification, "Test 2, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - plugin.parentNode.removeChild(plugin); + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + plugin.parentNode.removeChild(plugin); + }); - executeSoon(test3); -} - -function test3() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser); ok(popupNotification, "Test 3, Should still have a click-to-play notification"); - - finishTest(); -} +}); diff --git a/browser/base/content/test/plugins/browser_CTP_notificationBar.js b/browser/base/content/test/plugins/browser_CTP_notificationBar.js index f0cd4063fea5..c1c5ef1752f7 100644 --- a/browser/base/content/test/plugins/browser_CTP_notificationBar.js +++ b/browser/base/content/test/plugins/browser_CTP_notificationBar.js @@ -1,171 +1,154 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; -var gTestBrowser = null; -var gNextTest = null; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; }); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - var newTab = gBrowser.addTab(); + let newTab = gBrowser.addTab(); gBrowser.selectedTab = newTab; gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); +}); +add_task(function* () { Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); - prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_small.html"); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_small.html"); -function finishTest() { - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} + yield promisePopupNotification("click-to-play-plugins"); -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} + // Expecting a notification bar for hidden plugins + yield promiseForNotificationBar("plugin-hidden", gTestBrowser); +}); -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} +add_task(function* () { + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); -// Tests for the notification bar for hidden plugins. + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_small.html"); -function test1() { - info("Test 1 - expecting a notification bar for hidden plugins."); - waitForNotificationPopup("click-to-play-plugins", gTestBrowser, () => { - waitForNotificationBar("plugin-hidden", gTestBrowser, () => { - // Don't use setTestPluginEnabledState here because we already saved the - // prior value - getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED; - prepareTest(test2, gTestRoot + "plugin_small.html"); - }); - }); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -function test2() { - info("Test 2 - expecting no plugin notification bar on visible plugins."); - waitForNotificationPopup("click-to-play-plugins", gTestBrowser, () => { - let notificationBox = gBrowser.getNotificationBox(gTestBrowser); - - waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null, - () => { - getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY; - prepareTest(test3, gTestRoot + "plugin_overlayed.html"); - }, - "expected to not have a plugin notification bar" - ); - }); -} - -function test3() { - info("Test 3 - expecting a plugin notification bar when plugins are overlaid"); - waitForNotificationPopup("click-to-play-plugins", gTestBrowser, () => { - waitForNotificationBar("plugin-hidden", gTestBrowser, test3b); - }); -} - -function test3b() -{ - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("test"); - ok(plugin, "Test 3b, Found plugin in page"); - plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(plugin.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, - "Test 3b, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); - ok(!plugin.activated, "Test 3b, Plugin should not be activated"); - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(!overlay.classList.contains("visible"), "Test 3b, Plugin overlay should be hidden"); - - prepareTest(test4, gTestRoot + "plugin_positioned.html"); -} - -function test4() { - info("Test 4 - expecting a plugin notification bar when plugins are overlaid offscreen") - waitForNotificationPopup("click-to-play-plugins", gTestBrowser, () => { - waitForNotificationBar("plugin-hidden", gTestBrowser, test4b); - }); -} - -function test4b() { - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("test"); - ok(plugin, "Test 4b, Found plugin in page"); - plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(plugin.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, - "Test 4b, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); - ok(!plugin.activated, "Test 4b, Plugin should not be activated"); - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(!overlay.classList.contains("visible"), "Test 4b, Plugin overlay should be hidden"); - - prepareTest(runAfterPluginBindingAttached(test5), gHttpTestRoot + "plugin_small.html"); -} - -function test5() { let notificationBox = gBrowser.getNotificationBox(gTestBrowser); - waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") !== null, - test6, - "Test 5, expected a notification bar for hidden plugins"); -} + yield promiseForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null); +}); + +add_task(function* () { + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_overlayed.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + // Expecting a plugin notification bar when plugins are overlaid. + yield promiseForNotificationBar("plugin-hidden", gTestBrowser); +}); + +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_overlayed.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return plugin.pluginFallbackType; + }); + is(result, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, + "Test 3b, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 1a, plugin should not be activated"); + + result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(!result, "Test 3b, overlay should be hidden."); +}); + +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_positioned.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + // Expecting a plugin notification bar when plugins are overlaid offscreen. + yield promisePopupNotification("click-to-play-plugins"); + yield promiseForNotificationBar("plugin-hidden", gTestBrowser); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return plugin.pluginFallbackType; + }); + is(result, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, + "Test 4b, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); + + result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(!result, "Test 4b, overlay should be hidden."); +}); // Test that the notification bar is getting dismissed when directly activating plugins // via the doorhanger. -function test6() { - info("Test 6 - expecting the doorhanger to be dismissed when directly activating plugins."); - waitForNotificationPopup("click-to-play-plugins", gTestBrowser, (notification) => { - let plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(plugin, "Test 6, Found plugin in page"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, - "Test 6, Plugin should be click-to-play"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_small.html"); - // simulate "always allow" - notification.reshow(); - PopupNotifications.panel.firstChild._primaryButton.click(); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); - let notificationBox = gBrowser.getNotificationBox(gTestBrowser); - waitForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null, - test7, - "Test 6, expected the notification bar for hidden plugins to get dismissed"); + // Expecting a plugin notification bar when plugins are overlaid offscreen. + yield promisePopupNotification("click-to-play-plugins"); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return plugin.pluginFallbackType; }); -} + is(result, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, + "Test 6, Plugin should be click-to-play"); -function test7() { - let plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(plugin, "Test 7, Found plugin in page"); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - waitForCondition(() => objLoadingContent.activated, finishTest, - "Test 7, Waited too long for plugin to activate"); -} + yield promisePopupNotification("click-to-play-plugins"); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 6, Should have a click-to-play notification"); + + // simulate "always allow" + yield promiseForNotificationShown(notification); + + PopupNotifications.panel.firstChild._primaryButton.click(); + + let notificationBox = gBrowser.getNotificationBox(gTestBrowser); + yield promiseForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 7, plugin should be activated"); +}); diff --git a/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js b/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js index e30e20b2bf3c..138b6ccfdaff 100644 --- a/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js +++ b/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js @@ -1,125 +1,120 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); -var gRunNextTestAfterPluginRemoved = false; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; }); +}); + +add_task(function* () { + Services.prefs.setBoolPref("plugins.click_to_play", true); Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - var newTab = gBrowser.addTab(); + let newTab = gBrowser.addTab(); gBrowser.selectedTab = newTab; gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); - prepareTest(test1, gHttpTestRoot + "plugin_outsideScrollArea.html"); -} - -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} - -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} - -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} - -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} - -// Add plugin relative to bottom-left corner of #container. -function addPlugin(x, y) { - let doc = gTestBrowser.contentDocument; - let p = doc.createElement('embed'); - - p.setAttribute('id', 'test'); - p.setAttribute('type', 'application/x-test'); - p.style.left = x.toString() + 'px'; - p.style.bottom = y.toString() + 'px'; - - doc.getElementById('container').appendChild(p); -} + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!popupNotification, "Test 1, Should not have a click-to-play notification"); +}); // Test that the click-to-play overlay is not hidden for elements // partially or fully outside the viewport. -function test1() { - addPlugin(0, -200); - executeSoon(runAfterPluginBindingAttached(test2)); -} +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html"); -function test2() { - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("test"); - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Test 2, Should have an overlay."); - ok(overlay.classList.contains("visible"), "Test 2, Overlay should be visible"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let p = doc.createElement('embed'); - prepareTest(test3, gHttpTestRoot + "plugin_outsideScrollArea.html"); -} + p.setAttribute('id', 'test'); + p.setAttribute('type', 'application/x-test'); + p.style.left = "0"; + p.style.bottom = "200px"; -function test3() { - addPlugin(0, -410); - executeSoon(runAfterPluginBindingAttached(test4)); -} + doc.getElementById('container').appendChild(p); + }); -function test4() { - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("test"); - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Test 4, Should have an overlay."); - ok(overlay.classList.contains("visible"), "Test 4, Overlay should be visible"); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); - prepareTest(test5, gHttpTestRoot + "plugin_outsideScrollArea.html"); -} + yield promisePopupNotification("click-to-play-plugins"); -function test5() { - addPlugin(-600, 0); - executeSoon(runAfterPluginBindingAttached(test6)); -} + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let doc = content.document; + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Test 2, overlay should be visible."); +}); -function test6() { - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("test"); - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Test 6, Should have an overlay."); - ok(!overlay.classList.contains("visible"), "Test 6, Overlay should be hidden"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html"); - finishTest(); -} + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let p = doc.createElement('embed'); + + p.setAttribute('id', 'test'); + p.setAttribute('type', 'application/x-test'); + p.style.left = "0"; + p.style.bottom = "-410px"; + + doc.getElementById('container').appendChild(p); + }); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + yield promisePopupNotification("click-to-play-plugins"); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let doc = content.document; + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Test 3, overlay should be visible."); +}); + +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let p = doc.createElement('embed'); + + p.setAttribute('id', 'test'); + p.setAttribute('type', 'application/x-test'); + p.style.left = "-600px"; + p.style.bottom = "0"; + + doc.getElementById('container').appendChild(p); + }); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + yield promisePopupNotification("click-to-play-plugins"); + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let doc = content.document; + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(!result, "Test 4, overlay should be hidden."); +}); diff --git a/browser/base/content/test/plugins/browser_CTP_remove_navigate.js b/browser/base/content/test/plugins/browser_CTP_remove_navigate.js index 35c2207a39bf..8ee1c5b5aa9d 100644 --- a/browser/base/content/test/plugins/browser_CTP_remove_navigate.js +++ b/browser/base/content/test/plugins/browser_CTP_remove_navigate.js @@ -1,17 +1,23 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - const gTestRoot = getRootDirectory(gTestPath); const gHttpTestRoot = gTestRoot.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); add_task(function* () { - Services.prefs.setBoolPref("plugins.click_to_play", true); - registerCleanupFunction(() => { + registerCleanupFunction(function () { + clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); Services.prefs.clearUserPref("plugins.click_to_play"); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); }); -}) + + Services.prefs.setBoolPref("plugins.click_to_play", true); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); +}); /** * Tests that if a plugin is removed just as we transition to @@ -19,30 +25,27 @@ add_task(function* () { * notification bar on the new page. */ add_task(function* () { - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - let browser = gBrowser.selectedBrowser; - - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + gBrowser.selectedTab = gBrowser.addTab(); // Load up a page with a plugin... - let notificationPromise = - waitForNotificationBar("plugin-hidden", gBrowser.selectedBrowser); - yield loadPage(browser, gHttpTestRoot + "plugin_small.html") - yield forcePluginBindingAttached(browser); + let notificationPromise = waitForNotificationBar("plugin-hidden", gBrowser.selectedBrowser); + yield promiseTabLoadEvent(gBrowser.selectedTab, gHttpTestRoot + "plugin_small.html"); + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); yield notificationPromise; // Trigger the PluginRemoved event to be fired, and then immediately // browse to a new page. - let plugin = browser.contentDocument.getElementById("test"); - plugin.remove(); - yield loadPage(browser, "about:mozilla"); + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + plugin.remove(); + }); + + yield promiseTabLoadEvent(gBrowser.selectedTab, "about:mozilla"); // There should be no hidden plugin notification bar at about:mozilla. - let notificationBox = gBrowser.getNotificationBox(browser); + let notificationBox = gBrowser.getNotificationBox(gBrowser.selectedBrowser); is(notificationBox.getNotificationWithValue("plugin-hidden"), null, "Expected no notification box"); - gBrowser.removeTab(newTab); }); /** @@ -51,32 +54,26 @@ add_task(function* () { * for the new page. */ add_task(function* () { - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - let browser = gBrowser.selectedBrowser; - - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, - "Second Test Plug-in"); - // Load up a page with a plugin... - let notificationPromise = - waitForNotificationBar("plugin-hidden", browser); - yield loadPage(browser, gHttpTestRoot + "plugin_small.html") - yield forcePluginBindingAttached(browser); + let notificationPromise = waitForNotificationBar("plugin-hidden", gBrowser.selectedBrowser); + yield promiseTabLoadEvent(gBrowser.selectedTab, gHttpTestRoot + "plugin_small.html"); + yield promiseUpdatePluginBindings(gBrowser.selectedBrowser); yield notificationPromise; // Trigger the PluginRemoved event to be fired, and then immediately // browse to a new page. - let plugin = browser.contentDocument.getElementById("test"); - plugin.remove(); - yield loadPage(browser, gTestRoot + "plugin_small_2.html"); - let notification = yield waitForNotificationBar("plugin-hidden", browser); - ok(notification, "There should be a notification shown for the new page."); + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + plugin.remove(); + }); +}); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gHttpTestRoot + "plugin_small_2.html"); + let notification = yield waitForNotificationBar("plugin-hidden", gBrowser.selectedBrowser); + ok(notification, "There should be a notification shown for the new page."); // Ensure that the notification is showing information about // the x-second-test plugin. - ok(notification.label.includes("Second Test"), "Should mention the second plugin"); - ok(!notification.label.includes("127.0.0.1"), "Should not refer to old principal"); - ok(notification.label.includes("null"), "Should refer to the new principal"); - gBrowser.removeTab(newTab); + let label = notification.label; + ok(label.includes("Second Test"), "Should mention the second plugin"); }); diff --git a/browser/base/content/test/plugins/browser_CTP_resize.js b/browser/base/content/test/plugins/browser_CTP_resize.js index 1f381a8294c9..8e54544113a3 100644 --- a/browser/base/content/test/plugins/browser_CTP_resize.js +++ b/browser/base/content/test/plugins/browser_CTP_resize.js @@ -1,116 +1,130 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; }); +}); + +add_task(function* () { + Services.prefs.setBoolPref("plugins.click_to_play", true); Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - var newTab = gBrowser.addTab(); + let newTab = gBrowser.addTab(); gBrowser.selectedTab = newTab; gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); - prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_small.html"); -} + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!popupNotification, "Test 1, Should not have a click-to-play notification"); -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + yield promiseTabLoadEvent(newTab, gTestRoot + "plugin_small.html"); // 10x10 plugin -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} - -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} + yield promisePopupNotification("click-to-play-plugins"); +}); // Test that the overlay is hidden for "small" plugin elements and is shown // once they are resized to a size that can hold the overlay - -function test1() { +add_task(function* () { let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 1, Should have a click-to-play notification"); + ok(popupNotification, "Test 2, Should have a click-to-play notification"); - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let doc = gTestBrowser.contentDocument; - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Test 1, Should have an overlay."); - ok(!overlay.classList.contains("visible"), "Test 1, Overlay should be hidden"); + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(!result, "Test 2, overlay should be hidden."); +}); - plugin.style.width = '300px'; - executeSoon(test2); -} +add_task(function* () { + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + plugin.style.width = "300px"; + }); -function test2() { - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let doc = gTestBrowser.contentDocument; - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Test 2, Should have an overlay."); - ok(!overlay.classList.contains("visible"), "Test 2, Overlay should be hidden"); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); - plugin.style.height = '300px'; - let condition = () => overlay.classList.contains("visible"); - waitForCondition(condition, test3, "Test 2, Waited too long for overlay to become visible"); -} + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(!result, "Test 3, overlay should be hidden."); +}); -function test3() { - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let doc = gTestBrowser.contentDocument; - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Test 3, Should have an overlay."); - ok(overlay.classList.contains("visible"), "Test 3, Overlay should be visible"); - plugin.style.width = '10px'; - plugin.style.height = '10px'; - let condition = () => !overlay.classList.contains("visible"); - waitForCondition(condition, test4, "Test 3, Waited too long for overlay to become hidden"); -} +add_task(function* () { + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + plugin.style.height = "300px"; + }); -function test4() { - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let doc = gTestBrowser.contentDocument; - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Test 4, Should have an overlay."); - ok(!overlay.classList.contains("visible"), "Test 4, Overlay should be hidden"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + content.document.getElementById("test").clientTop; + }); - clearAllPluginPermissions(); - finishTest(); -} + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Test 4, overlay should be visible."); +}); + +add_task(function* () { + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + plugin.style.width = "10px"; + plugin.style.height = "10px"; + }); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + content.document.getElementById("test").clientTop; + }); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(!result, "Test 5, overlay should be hidden."); +}); + +add_task(function* () { + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + plugin.style.height = "300px"; + plugin.style.width = "300px"; + }); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + content.document.getElementById("test").clientTop; + }); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Test 6, overlay should be visible."); +}); diff --git a/browser/base/content/test/plugins/browser_CTP_zoom.js b/browser/base/content/test/plugins/browser_CTP_zoom.js index 6d351786ac9a..0cfd85144c8e 100644 --- a/browser/base/content/test/plugins/browser_CTP_zoom.js +++ b/browser/base/content/test/plugins/browser_CTP_zoom.js @@ -1,77 +1,62 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - "use strict"; let rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", - "http://127.0.0.1:8888/"); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); let gTestBrowser = null; -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(() => { - FullZoom.reset(); +add_task(function* () { + registerCleanupFunction(function () { clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + FullZoom.reset(); // must be called before closing the tab we zoomed! + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; }); +}); + +add_task(function* () { + Services.prefs.setBoolPref("plugins.click_to_play", true); Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; + gBrowser.selectedTab = gBrowser.addTab(); gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_zoom.html" -} -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); -function pageLoad() { - // Due to layout being async, "PluginBindAttached" may trigger later. - // This wraps a function to force a layout flush, thus triggering it, - // and schedules the function execution so they're definitely executed - // afterwards. - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(testOverlay); -} + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!popupNotification, "Test 1, Should not have a click-to-play notification"); -let enlargeCount = 4; + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_zoom.html"); -// Enlarges the zoom level |enlargeCount| times and tests that the overlay is + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + yield promisePopupNotification("click-to-play-plugins"); +}); + +// Enlarges the zoom level 4 times and tests that the overlay is // visible after each enlargement. -function testOverlay() { - let plugin = gTestBrowser.contentDocument.getElementById("test"); - let doc = gTestBrowser.contentDocument; - let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay, "Overlay should exist"); - ok(overlay.classList.contains("visible"), "Overlay should be visible"); +add_task(function* () { + for (let count = 0; count < 4; count++) { - if (enlargeCount > 0) { - --enlargeCount; FullZoom.enlarge(); - gTestBrowser.contentWindow.location.reload(); - } else { - FullZoom.reset(); - clearAllPluginPermissions(); - finishTest(); + + // Reload the page + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_zoom.html"); + yield promiseUpdatePluginBindings(gTestBrowser); + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Overlay should be visible for zoom change count " + count); } -} +}); + + diff --git a/browser/base/content/test/plugins/browser_blocking.js b/browser/base/content/test/plugins/browser_blocking.js new file mode 100644 index 000000000000..f3b2df009816 --- /dev/null +++ b/browser/base/content/test/plugins/browser_blocking.js @@ -0,0 +1,360 @@ +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); + +function updateAllTestPlugins(aState) { + setTestPluginEnabledState(aState, "Test Plug-in"); + setTestPluginEnabledState(aState, "Second Test Plug-in"); +} + +add_task(function* () { + registerCleanupFunction(Task.async(function*() { + clearAllPluginPermissions(); + updateAllTestPlugins(Ci.nsIPluginTag.STATE_ENABLED); + Services.prefs.clearUserPref("plugins.click_to_play"); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + resetBlocklist(); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; + })); +}); + +add_task(function* () { + gBrowser.selectedTab = gBrowser.addTab(); + gTestBrowser = gBrowser.selectedBrowser; + + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.setBoolPref("plugins.click_to_play", true); + + // Prime the content process + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,hi"); + + // Make sure the blocklist service(s) are running + Components.classes["@mozilla.org/extensions/blocklist;1"] + .getService(Components.interfaces.nsIBlocklistService); + let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser); + ok(!exmsg, "exception: " + exmsg); +}); + +add_task(function* () { + // enable hard blocklisting for the next test + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginHard.xml", gTestBrowser); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + yield promisePopupNotification("click-to-play-plugins"); + + let notification = PopupNotifications.getNotification("click-to-play-plugins"); + ok(notification.dismissed, "Test 5: The plugin notification should be dismissed by default"); + + yield promiseForNotificationShown(notification); + + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED, "Test 5, plugin fallback type should be PLUGIN_BLOCKLISTED"); + + is(notification.options.pluginData.size, 1, "Test 5: Only the blocked plugin should be present in the notification"); + ok(PopupNotifications.panel.firstChild._buttonContainer.hidden, "Part 5: The blocked plugins notification should not have any buttons visible."); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); +}); + +// Tests a vulnerable, updatable plugin + +add_task(function* () { + // enable hard blocklisting of test + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableUpdatable.xml", gTestBrowser); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + yield promisePopupNotification("click-to-play-plugins"); + + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, + "Test 18a, plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE"); + ok(!pluginInfo.activated, "Test 18a, Plugin should not be activated"); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let doc = content.document; + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Test 18a, Plugin overlay should exist, not be hidden"); + + result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink"); + return updateLink.style.visibility != "hidden"; + }); + ok(result, "Test 18a, Plugin should have an update link"); + + let promise = waitForEvent(gBrowser.tabContainer, "TabOpen", null, true); + let pluginUpdateURL = Services.urlFormatter.formatURLPref("plugins.update.url"); + info(pluginUpdateURL); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink"); + let bounds = updateLink.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); + yield promise; + + promise = waitForEvent(gBrowser.tabContainer, "TabClose", null, true); + gBrowser.removeCurrentTab(); + yield promise; +}); + +add_task(function* () { + // clicking the update link should not activate the plugin + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, + "Test 18a, plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE"); + ok(!pluginInfo.activated, "Test 18b, Plugin should not be activated"); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Test 18b, Plugin overlay should exist, not be hidden"); +}); + +// Tests a vulnerable plugin with no update +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableNoUpdate.xml", gTestBrowser); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 18c, Should have a click-to-play notification"); + + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE, + "Test 18c, plugin fallback type should be PLUGIN_VULNERABLE_NO_UPDATE"); + ok(!pluginInfo.activated, "Test 18c, Plugin should not be activated"); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return overlay && overlay.classList.contains("visible"); + }); + ok(result, "Test 18c, Plugin overlay should exist, not be hidden"); + + result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink"); + return updateLink && updateLink.style.display != "block"; + }); + ok(result, "Test 18c, Plugin should not have an update link"); + + // check that click "Always allow" works with blocked plugins + yield promiseForNotificationShown(notification); + + PopupNotifications.panel.firstChild._primaryButton.click(); + + pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE, + "Test 18c, plugin fallback type should be PLUGIN_VULNERABLE_NO_UPDATE"); + ok(pluginInfo.activated, "Test 18c, Plugin should be activated"); + let enabledState = getTestPluginEnabledState(); + ok(enabledState, "Test 18c, Plugin enabled state should be STATE_CLICKTOPLAY"); +}); + +// continue testing "Always allow", make sure it sticks. +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 18d, Waited too long for plugin to activate"); + + clearAllPluginPermissions(); +}); + +// clicking the in-content overlay of a vulnerable plugin should bring +// up the notification and not directly activate the plugin +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 18f, Should have a click-to-play notification"); + ok(notification.dismissed, "Test 18f, notification should start dismissed"); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 18f, Waited too long for plugin to activate"); + + var oldEventCallback = notification.options.eventCallback; + let promise = promiseForCondition(() => oldEventCallback == null); + notification.options.eventCallback = function() { + if (oldEventCallback) { + oldEventCallback(); + } + oldEventCallback = null; + }; + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); + yield promise; + + ok(notification, "Test 18g, Should have a click-to-play notification"); + ok(!notification.dismissed, "Test 18g, notification should be open"); + + pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated"); +}); + +// Test that "always allow"-ing a plugin will not allow it when it becomes +// blocklisted. +add_task(function* () { + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 24a, Should have a click-to-play notification"); + + // Plugin should start as CTP + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, + "Test 24a, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); + ok(!pluginInfo.activated, "Test 24a, Plugin should not be active."); + + // simulate "always allow" + yield promiseForNotificationShown(notification); + + PopupNotifications.panel.firstChild._primaryButton.click(); + + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 24a, Plugin should be active."); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableUpdatable.xml", gTestBrowser); +}); + +// the plugin is now blocklisted, so it should not automatically load +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 24b, Should have a click-to-play notification"); + + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, + "Test 24b, plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE"); + ok(!pluginInfo.activated, "Test 24b, Plugin should not be active."); + + // simulate "always allow" + yield promiseForNotificationShown(notification); + + PopupNotifications.panel.firstChild._primaryButton.click(); + + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 24b, Plugin should be active."); + + clearAllPluginPermissions(); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); +}); + +// Plugin sync removal test. Note this test produces a notification drop down since +// the plugin we add has zero dims. +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_syncRemoved.html"); + + // Maybe there some better trick here, we need to wait for the page load, then + // wait for the js to execute in the page. + yield waitForMs(500); + + let notification = PopupNotifications.getNotification("click-to-play-plugins"); + ok(notification, "Test 25: There should be a plugin notification even if the plugin was immediately removed"); + ok(notification.dismissed, "Test 25: The notification should be dismissed by default"); + + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,hi"); +}); + +// Tests a page with a blocked plugin in it and make sure the infoURL property +// the blocklist file gets used. +add_task(function* () { + clearAllPluginPermissions(); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginInfoURL.xml", gTestBrowser); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins"); + + // Since the plugin notification is dismissed by default, reshow it. + yield promiseForNotificationShown(notification); + + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED, + "Test 26, plugin fallback type should be PLUGIN_BLOCKLISTED"); + + let result = ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(result, "Plugin should be activated."); + + const testUrl = "http://test.url.com/"; + + let firstPanelChild = PopupNotifications.panel.firstChild; + let infoLink = document.getAnonymousElementByAttribute(firstPanelChild, "anonid", + "click-to-play-plugins-notification-link"); + is(infoLink.href, testUrl, + "Test 26, the notification URL needs to match the infoURL from the blocklist file."); +}); + diff --git a/browser/base/content/test/plugins/browser_blocklist_content.js b/browser/base/content/test/plugins/browser_blocklist_content.js new file mode 100644 index 000000000000..e666f2e3137f --- /dev/null +++ b/browser/base/content/test/plugins/browser_blocklist_content.js @@ -0,0 +1,108 @@ +let gTestBrowser = null; +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gChromeRoot = getRootDirectory(gTestPath); + +add_task(function* () { + registerCleanupFunction(Task.async(function*() { + clearAllPluginPermissions(); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + Services.prefs.clearUserPref("plugins.click_to_play"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + resetBlocklist(); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; + })); +}); + +add_task(function* () { + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.setBoolPref("plugins.click_to_play", true); + + gBrowser.selectedTab = gBrowser.addTab(); + gTestBrowser = gBrowser.selectedBrowser; + + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + + // Prime the blocklist service, the remote service doesn't launch on startup. + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,"); + let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser); + ok(!exmsg, "exception: " + exmsg); +}); + +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let test = content.document.getElementById("test"); + return test.activated; + }); + ok(result, "task 1a: test plugin should be activated!"); +}); + +// Load a fresh page, load a new plugin blocklist, then load the same page again. +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,GO!"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginHard.xml", gTestBrowser); + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let test = content.document.getElementById("test"); + return test.activated; + }); + ok(!result, "task 2a: test plugin shouldn't activate!"); +}); + +// Unload the block list and lets do this again, only this time lets +// hack around in the content blocklist service maliciously. +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,GO!"); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + + // Hack the planet! Load our blocklist shim, so we can mess with blocklist + // return results in the content process. Active until we close our tab. + let mm = gTestBrowser.messageManager; + info("test 3a: loading " + gChromeRoot + "blocklist_proxy.js" + "\n"); + mm.loadFrameScript(gChromeRoot + "blocklist_proxy.js", true); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let test = content.document.getElementById("test"); + return test.activated; + }); + ok(result, "task 3a: test plugin should be activated!"); +}); + +// Load a fresh page, load a new plugin blocklist, then load the same page again. +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,GO!"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginHard.xml", gTestBrowser); + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let test = content.document.getElementById("test"); + return test.activated; + }); + ok(!result, "task 4a: test plugin shouldn't activate!"); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); +}); diff --git a/browser/base/content/test/plugins/browser_bug743421.js b/browser/base/content/test/plugins/browser_bug743421.js index 10f7f62835ab..4519aac9a654 100644 --- a/browser/base/content/test/plugins/browser_bug743421.js +++ b/browser/base/content/test/plugins/browser_bug743421.js @@ -1,114 +1,127 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/"); +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; -var gTestBrowser = null; -var gNextTest = null; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(Task.async(function*() { clearAllPluginPermissions(); Services.prefs.clearUserPref("plugins.click_to_play"); - }); - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + resetBlocklist(); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; + })); +}); - var newTab = gBrowser.addTab(); +add_task(function* () { + let newTab = gBrowser.addTab(); gBrowser.selectedTab = newTab; gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - prepareTest(test1a, gTestRoot + "plugin_add_dynamically.html"); -} -function finishTest() { - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.setBoolPref("plugins.click_to_play", true); -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} + // Prime the blocklist service, the remote service doesn't launch on startup. + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,"); + + let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser); + ok(!exmsg, "exception: " + exmsg); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); +}); // Tests that navigation within the page and the window.history API doesn't break click-to-play state. -function test1a() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(!popupNotification, "Test 1a, Should not have a click-to-play notification"); - var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin()); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_add_dynamically.html"); - var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin notification"); -} + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!notification, "Test 1a, Should not have a click-to-play notification"); -function test1b() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 1b, Should have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0]; - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin()); + }); + + yield promisePopupNotification("click-to-play-plugins"); +}); + +add_task(function* () { + let isActivated = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementsByTagName("embed")[0]; + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(!isActivated, "Test 1b, Plugin should not be activated"); // Click the activate button on doorhanger to make sure it works - popupNotification.reshow(); + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + + yield promiseForNotificationShown(notification); + PopupNotifications.panel.firstChild._primaryButton.click(); - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test1c, "Test 1b, Waited too long for plugin activation"); -} -function test1c() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 1c, Should still have a click-to-play notification"); - var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin()); + isActivated = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementsByTagName("embed")[0]; + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(isActivated, "Test 1b, Plugin should be activated"); +}); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test1d, "Test 1c, Waited too long for plugin activation"); -} +add_task(function* () { + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 1c, Should still have a click-to-play notification"); -function test1d() { - var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[1]; - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 1d, Plugin should be activated"); + let isActivated = yield ContentTask.spawn(gTestBrowser, {}, function* () { + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin()); + let plugin = content.document.getElementsByTagName("embed")[1]; + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(isActivated, "Test 1c, Newly inserted plugin in activated page should be activated"); +}); - gNextTest = test1e; - gTestBrowser.contentWindow.addEventListener("hashchange", test1e, false); +add_task(function* () { + let isActivated = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementsByTagName("embed")[1]; + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(isActivated, "Test 1d, Plugin should be activated"); + + let promise = waitForEvent(gTestBrowser.contentWindow, "hashchange", null); gTestBrowser.contentWindow.location += "#anchorNavigation"; -} + yield promise; +}); -function test1e() { - gTestBrowser.contentWindow.removeEventListener("hashchange", test1e, false); +add_task(function* () { + let isActivated = yield ContentTask.spawn(gTestBrowser, {}, function* () { + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin()); + let plugin = content.document.getElementsByTagName("embed")[2]; + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(isActivated, "Test 1e, Plugin should be activated"); +}); - var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin()); +add_task(function* () { + let isActivated = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementsByTagName("embed")[2]; + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(isActivated, "Test 1f, Plugin should be activated"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test1f, "Test 1e, Waited too long for plugin activation"); -} - -function test1f() { - var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[2]; - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 1f, Plugin should be activated"); - - gTestBrowser.contentWindow.history.replaceState({}, "", "replacedState"); - var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin()); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test1g, "Test 1f, Waited too long for plugin activation"); -} - -function test1g() { - var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[3]; - var objLoadingContent2 = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent2.activated, "Test 1g, Plugin should be activated"); - finishTest(); -} + isActivated = yield ContentTask.spawn(gTestBrowser, {}, function* () { + content.history.replaceState({}, "", "replacedState"); + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin()); + let plugin = content.document.getElementsByTagName("embed")[3]; + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + return objLoadingContent.activated; + }); + ok(isActivated, "Test 1f, Plugin should not be activated"); +}); diff --git a/browser/base/content/test/plugins/browser_bug744745.js b/browser/base/content/test/plugins/browser_bug744745.js index 5d90ee2ffdf5..553cf70e2427 100644 --- a/browser/base/content/test/plugins/browser_bug744745.js +++ b/browser/base/content/test/plugins/browser_bug744745.js @@ -1,43 +1,51 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var gTestBrowser = null; -var gNumPluginBindingsAttached = 0; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { - Services.prefs.clearUserPref("plugins.click_to_play"); - gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true, true); - gBrowser.removeCurrentTab(); - window.focus(); - }); - - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - - gBrowser.selectedTab = gBrowser.addTab(); - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true); - var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); - gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug744745.html"; -} +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; +let gNumPluginBindingsAttached = 0; function pluginBindingAttached() { gNumPluginBindingsAttached++; - - if (gNumPluginBindingsAttached == 1) { - var doc = gTestBrowser.contentDocument; - var testplugin = doc.getElementById("test"); - ok(testplugin, "should have test plugin"); - var style = getComputedStyle(testplugin); - ok('opacity' in style, "style should have opacity set"); - is(style.opacity, 1, "opacity should be 1"); - finish(); - } else { + if (gNumPluginBindingsAttached != 1) { ok(false, "if we've gotten here, something is quite wrong"); } } + +add_task(function* () { + registerCleanupFunction(function () { + gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true, true); + clearAllPluginPermissions(); + Services.prefs.clearUserPref("plugins.click_to_play"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; + }); +}); + +add_task(function* () { + gBrowser.selectedTab = gBrowser.addTab(); + gTestBrowser = gBrowser.selectedBrowser; + + Services.prefs.setBoolPref("plugins.click_to_play", true); + + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + + gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true); + + let testRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); + yield promiseTabLoadEvent(gBrowser.selectedTab, testRoot + "plugin_bug744745.html"); + + yield promiseForCondition(function () { return gNumPluginBindingsAttached == 1; }); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + if (!plugin) { + return false; + } + // We can't use MochiKit's routine + let style = content.getComputedStyle(plugin); + return 'opacity' in style && style.opacity == 1; + }); + + ok(result, true, "plugin style properly configured."); +}); diff --git a/browser/base/content/test/plugins/browser_bug787619.js b/browser/base/content/test/plugins/browser_bug787619.js index 5d3db3d1a97b..5cb28bb913c0 100644 --- a/browser/base/content/test/plugins/browser_bug787619.js +++ b/browser/base/content/test/plugins/browser_bug787619.js @@ -1,49 +1,65 @@ -const gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); - +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); let gTestBrowser = null; let gWrapperClickCount = 0; -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { + clearAllPluginPermissions(); Services.prefs.clearUserPref("plugins.click_to_play"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; }); +}); + +add_task(function* () { Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); gBrowser.selectedTab = gBrowser.addTab(); gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug787619.html"; -} -function pageLoad() { + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + + let testRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); + yield promiseTabLoadEvent(gBrowser.selectedTab, testRoot + "plugin_bug787619.html"); + // Due to layout being async, "PluginBindAttached" may trigger later. // This forces a layout flush, thus triggering it, and schedules the // test so it is definitely executed afterwards. - gTestBrowser.contentDocument.getElementById('plugin').clientTop; - executeSoon(part1); -} + yield promiseUpdatePluginBindings(gTestBrowser); -function part1() { - let wrapper = gTestBrowser.contentDocument.getElementById('wrapper'); - wrapper.addEventListener('click', function() ++gWrapperClickCount, false); + // check plugin state + let pluginInfo = yield promiseForPluginInfo("plugin"); + ok(!pluginInfo.activated, "1a plugin should not be activated"); - let plugin = gTestBrowser.contentDocument.getElementById('plugin'); - ok(plugin, 'got plugin element'); - ok(!plugin.activated, 'plugin should not be activated'); - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Doorhanger should not be open"); + // click the overlay to prompt + let promise = promisePopupNotification("click-to-play-plugins"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("plugin"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); + yield promise; - EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow); - let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed; - waitForCondition(condition, part2, - 'waited too long for plugin to activate'); -} + // check plugin state + pluginInfo = yield promiseForPluginInfo("plugin"); + ok(!pluginInfo.activated, "1b plugin should not be activated"); + + let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed && + PopupNotifications.panel.firstChild; + yield promiseForCondition(condition); + PopupNotifications.panel.firstChild._primaryButton.click(); + + // check plugin state + pluginInfo = yield promiseForPluginInfo("plugin"); + ok(pluginInfo.activated, "plugin should be activated"); -function part2() { is(gWrapperClickCount, 0, 'wrapper should not have received any clicks'); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} +}); diff --git a/browser/base/content/test/plugins/browser_bug797677.js b/browser/base/content/test/plugins/browser_bug797677.js index f14dd3d35ddc..78db95117031 100644 --- a/browser/base/content/test/plugins/browser_bug797677.js +++ b/browser/base/content/test/plugins/browser_bug797677.js @@ -1,47 +1,45 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; +let gConsoleErrors = 0; -var rootDir = getRootDirectory(gTestPath); -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); const Cc = Components.classes; const Ci = Components.interfaces; -var gTestBrowser = null; -var gConsoleErrors = 0; -function test() { - waitForExplicitFinish(); - var newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; +add_task(function* () { + registerCleanupFunction(function () { + clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + consoleService.unregisterListener(errorListener); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; + }); + + gBrowser.selectedTab = gBrowser.addTab(); gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true); - var consoleService = Cc["@mozilla.org/consoleservice;1"] + + let bindingPromise = waitForEvent(gTestBrowser, "PluginBindingAttached", null, true, true); + + let consoleService = Cc["@mozilla.org/consoleservice;1"] .getService(Ci.nsIConsoleService); - var errorListener = { + let errorListener = { observe: function(aMessage) { - if (aMessage.message.includes("NS_ERROR")) + if (aMessage.message.includes("NS_ERROR_FAILURE")) gConsoleErrors++; } }; consoleService.registerListener(errorListener); - registerCleanupFunction(function() { - gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true); - consoleService.unregisterListener(errorListener); - gBrowser.removeCurrentTab(); - window.focus(); - }); - gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug797677.html"; -} -function pluginBindingAttached() { - // Let browser-plugins.js handle the PluginNotFound event, then run the test - executeSoon(runTest); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_bug797677.html"); -function runTest() { - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("plugin"); + yield bindingPromise; + + let pluginInfo = yield promiseForPluginInfo("plugin"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED, "plugin should not have been found."); + + // simple cpows + let plugin = gTestBrowser.contentDocument.getElementById("plugin"); ok(plugin, "plugin should be in the page"); is(gConsoleErrors, 0, "should have no console errors"); - finish(); -} +}); diff --git a/browser/base/content/test/plugins/browser_bug812562.js b/browser/base/content/test/plugins/browser_bug812562.js index 6bda448144c6..b3ff8c25af51 100644 --- a/browser/base/content/test/plugins/browser_bug812562.js +++ b/browser/base/content/test/plugins/browser_bug812562.js @@ -1,93 +1,80 @@ -var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); -var gTestBrowser = null; -var gNextTest = null; +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { - Services.prefs.clearUserPref("plugins.click_to_play"); - }); - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - - var newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml", - function() { - prepareTest(function() { - // Due to layout being async, "PluginBindAttached" may trigger later. - // This forces a layout flush, thus triggering it, and schedules the - // test so it is definitely executed afterwards. - gTestBrowser.contentDocument.getElementById('test').clientTop; - testPart1(); - }, - gHttpTestRoot + "plugin_test.html"); - }); -} - -function finishTest() { - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", - function() { +add_task(function* () { + registerCleanupFunction(Task.async(function*() { + clearAllPluginPermissions(); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); resetBlocklist(); - finish(); - }); -} + Services.prefs.clearUserPref("plugins.click_to_play"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; + })); + gBrowser.selectedTab = gBrowser.addTab(); + gTestBrowser = gBrowser.selectedBrowser; -function pageLoad(aEvent) { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - if (gNextTest != null) - executeSoon(gNextTest); -} + Services.prefs.setBoolPref("plugins.click_to_play", true); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} + // Prime the blocklist service, the remote service doesn't launch on startup. + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,"); + let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser); + ok(!exmsg, "exception: " + exmsg); +}); // Tests that the going back will reshow the notification for click-to-play -// blocklisted plugins (part 1/4) -function testPart1() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); +// blocklisted plugins +add_task(function* () { + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableUpdatable.xml", gTestBrowser); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); ok(popupNotification, "test part 1: Should have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "test part 1: plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE"); - ok(!objLoadingContent.activated, "test part 1: plugin should not be activated"); - prepareTest(testPart2, "about:blank"); -} + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "plugin should be marked as VULNERABLE"); -function testPart2() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + let found = yield ContentTask.spawn(gTestBrowser, {}, function* () { + return !!content.document.getElementById("test"); + }); + ok(found, "test part 1: plugin should not be activated"); + + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,"); +}); + +add_task(function* () { + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); ok(!popupNotification, "test part 2: Should not have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(!plugin, "test part 2: Should not have a plugin in this page"); + let found = yield ContentTask.spawn(gTestBrowser, {}, function* () { + return !!content.document.getElementById("test"); + }); + ok(!found, "test part 2: plugin should not be activated"); - Services.obs.addObserver(testPart3, "PopupNotifications-updateNotShowing", false); + let obsPromise = TestUtils.topicObserved("PopupNotifications-updateNotShowing"); + let overlayPromise = promisePopupNotification("click-to-play-plugins"); gTestBrowser.contentWindow.history.back(); -} + yield obsPromise; + yield overlayPromise; +}); -function testPart3() { - Services.obs.removeObserver(testPart3, "PopupNotifications-updateNotShowing"); - var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - waitForCondition(condition, testPart4, "test part 3: waited too long for click-to-play-plugin notification"); -} +add_task(function* () { + yield promiseUpdatePluginBindings(gTestBrowser); -function testPart4() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "test part 4: Should have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "test part 4: plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE"); - ok(!objLoadingContent.activated, "test part 4: plugin should not be activated"); + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(popupNotification, "test part 3: Should have a click-to-play notification"); - finishTest(); -} + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "plugin should be marked as VULNERABLE"); + + let found = yield ContentTask.spawn(gTestBrowser, {}, function* () { + return !!content.document.getElementById("test"); + }); + ok(found, "test part 3: plugin should not be activated"); +}); diff --git a/browser/base/content/test/plugins/browser_bug818118.js b/browser/base/content/test/plugins/browser_bug818118.js index 2fb27fbb2d4f..d5e701c42949 100644 --- a/browser/base/content/test/plugins/browser_bug818118.js +++ b/browser/base/content/test/plugins/browser_bug818118.js @@ -1,45 +1,38 @@ -var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); -var gTestBrowser = null; +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { + clearAllPluginPermissions(); Services.prefs.clearUserPref("plugins.click_to_play"); - gTestBrowser.removeEventListener("load", pageLoad, true); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; }); +}); +add_task(function* () { Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); gBrowser.selectedTab = gBrowser.addTab(); gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_both.html"; -} -function pageLoad(aEvent) { - // Due to layout being async, "PluginBindAttached" may trigger later. - // This forces a layout flush, thus triggering it, and schedules the - // test so it is definitely executed afterwards. - gTestBrowser.contentDocument.getElementById('test').clientTop; - executeSoon(actualTest); -} + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); -function actualTest() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_both.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); ok(popupNotification, "should have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(plugin, "should have known plugin in page"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); - ok(!objLoadingContent.activated, "plugin should not be activated"); - var unknown = gTestBrowser.contentDocument.getElementById("unknown"); + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "plugin should be click to play"); + ok(!pluginInfo.activated, "plugin should not be activated"); + + let unknown = gTestBrowser.contentDocument.getElementById("unknown"); ok(unknown, "should have unknown plugin in page"); - - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} +}); diff --git a/browser/base/content/test/plugins/browser_bug820497.js b/browser/base/content/test/plugins/browser_bug820497.js index e5ca402f88af..993c9660b390 100644 --- a/browser/base/content/test/plugins/browser_bug820497.js +++ b/browser/base/content/test/plugins/browser_bug820497.js @@ -1,61 +1,73 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestBrowser = null; +let gNumPluginBindingsAttached = 0; -var gTestBrowser = null; -var gNumPluginBindingsAttached = 0; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(function () { + clearAllPluginPermissions(); Services.prefs.clearUserPref("plugins.click_to_play"); - gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true, true); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); gBrowser.removeCurrentTab(); window.focus(); + gTestBrowser = null; }); +}); +add_task(function* () { Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); gBrowser.selectedTab = gBrowser.addTab(); gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true); - var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); - gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug820497.html"; -} -function pluginBindingAttached() { - gNumPluginBindingsAttached++; + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); - if (gNumPluginBindingsAttached == 1) { - var doc = gTestBrowser.contentDocument; - var testplugin = doc.getElementById("test"); + gTestBrowser.addEventListener("PluginBindingAttached", function () { gNumPluginBindingsAttached++ }, true, true); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_bug820497.html"); + + yield promiseForCondition(function () { return gNumPluginBindingsAttached == 1; }); + + // cpows + { + // Note we add the second plugin in the code farther down, so there's + // no way we got here with anything but one plugin loaded. + let doc = gTestBrowser.contentDocument; + let testplugin = doc.getElementById("test"); ok(testplugin, "should have test plugin"); - var secondtestplugin = doc.getElementById("secondtest"); + let secondtestplugin = doc.getElementById("secondtest"); ok(!secondtestplugin, "should not yet have second test plugin"); - var notification; - waitForNotificationPopup("click-to-play-plugins", gTestBrowser, (notification => { - ok(notification, "should have popup notification"); - // We don't set up the action list until the notification is shown - notification.reshow(); - is(notification.options.pluginData.size, 1, "should be 1 type of plugin in the popup notification"); - XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addSecondPlugin(); - })); - } else if (gNumPluginBindingsAttached == 2) { - var doc = gTestBrowser.contentDocument; - var testplugin = doc.getElementById("test"); - ok(testplugin, "should have test plugin"); - var secondtestplugin = doc.getElementById("secondtest"); - ok(secondtestplugin, "should have second test plugin"); - var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(notification, "should have popup notification"); - notification.reshow(); - let condition = () => (notification.options.pluginData.size == 2); - waitForCondition(condition, finish, "Waited too long for 2 types of plugins in popup notification"); - } else { - ok(false, "if we've gotten here, something is quite wrong"); } -} + + yield promisePopupNotification("click-to-play-plugins"); + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "should have a click-to-play notification"); + + yield promiseForNotificationShown(notification); + + is(notification.options.pluginData.size, 1, "should be 1 type of plugin in the popup notification"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + XPCNativeWrapper.unwrap(content).addSecondPlugin(); + }); + + yield promiseForCondition(function () { return gNumPluginBindingsAttached == 2; }); + + // cpows + { + let doc = gTestBrowser.contentDocument; + let testplugin = doc.getElementById("test"); + ok(testplugin, "should have test plugin"); + let secondtestplugin = doc.getElementById("secondtest"); + ok(secondtestplugin, "should have second test plugin"); + } + + notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + + ok(notification, "should have popup notification"); + + yield promiseForNotificationShown(notification); + + is(notification.options.pluginData.size, 2, "aited too long for 2 types of plugins in popup notification"); +}); diff --git a/browser/base/content/test/plugins/browser_clearplugindata.html b/browser/base/content/test/plugins/browser_clearplugindata.html index d5a6872c8999..243350ba42ab 100644 --- a/browser/base/content/test/plugins/browser_clearplugindata.html +++ b/browser/base/content/test/plugins/browser_clearplugindata.html @@ -21,8 +21,6 @@ "baz.com:1:5," + "qux.com:1:100" ); - - setTimeout(testFinishedCallback, 0); } diff --git a/browser/base/content/test/plugins/browser_clearplugindata.js b/browser/base/content/test/plugins/browser_clearplugindata.js index 69b601815bd7..6dea3504e85d 100644 --- a/browser/base/content/test/plugins/browser_clearplugindata.js +++ b/browser/base/content/test/plugins/browser_clearplugindata.js @@ -1,50 +1,63 @@ -/** - * Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -var rootDir = getRootDirectory(gTestPath); -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/"); +var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); +var gTestBrowser = null; // Test clearing plugin data using sanitize.js. -const testURL1 = gHttpTestRoot + "browser_clearplugindata.html"; -const testURL2 = gHttpTestRoot + "browser_clearplugindata_noage.html"; +const testURL1 = gTestRoot + "browser_clearplugindata.html"; +const testURL2 = gTestRoot + "browser_clearplugindata_noage.html"; -let tempScope = {}; +var tempScope = {}; Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader) .loadSubScript("chrome://browser/content/sanitize.js", tempScope); -let Sanitizer = tempScope.Sanitizer; +var Sanitizer = tempScope.Sanitizer; const pluginHostIface = Ci.nsIPluginHost; var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); pluginHost.QueryInterface(pluginHostIface); var pluginTag = getTestPlugin(); -var s; +var sanitizer = null; function stored(needles) { - var something = pluginHost.siteHasData(this.pluginTag, null); + let something = pluginHost.siteHasData(this.pluginTag, null); if (!needles) return something; if (!something) return false; - for (var i = 0; i < needles.length; ++i) { + for (let i = 0; i < needles.length; ++i) { if (!pluginHost.siteHasData(this.pluginTag, needles[i])) return false; } return true; } -function test() { - waitForExplicitFinish(); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED); +add_task(function* () { + registerCleanupFunction(function () { + clearAllPluginPermissions(); + Services.prefs.clearUserPref("plugins.click_to_play"); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + if (gTestBrowser) { + gBrowser.removeCurrentTab(); + } + window.focus(); + gTestBrowser = null; + }); +}); - s = new Sanitizer(); - s.ignoreTimespan = false; - s.prefDomain = "privacy.cpd."; - var itemPrefs = gPrefService.getBranch(s.prefDomain); +add_task(function* () { + Services.prefs.setBoolPref("plugins.click_to_play", true); + + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + + sanitizer = new Sanitizer(); + sanitizer.ignoreTimespan = false; + sanitizer.prefDomain = "privacy.cpd."; + let itemPrefs = gPrefService.getBranch(sanitizer.prefDomain); itemPrefs.setBoolPref("history", false); itemPrefs.setBoolPref("downloads", false); itemPrefs.setBoolPref("cache", false); @@ -54,80 +67,61 @@ function test() { itemPrefs.setBoolPref("passwords", false); itemPrefs.setBoolPref("sessions", false); itemPrefs.setBoolPref("siteSettings", false); +}); - executeSoon(test_with_age); -} - -function setFinishedCallback(callback) -{ - let testPage = gBrowser.selectedBrowser.contentWindow.wrappedJSObject; - testPage.testFinishedCallback = function() { - setTimeout(function() { - info("got finished callback"); - callback(); - }, 0); - } -} - -function test_with_age() -{ +add_task(function* () { // Load page to set data for the plugin. gBrowser.selectedTab = gBrowser.addTab(); - gBrowser.selectedBrowser.addEventListener("load", function () { - gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); + gTestBrowser = gBrowser.selectedBrowser; - setFinishedCallback(function() { - ok(stored(["foo.com","bar.com","baz.com","qux.com"]), - "Data stored for sites"); + yield promiseTabLoadEvent(gBrowser.selectedTab, testURL1); - // Clear 20 seconds ago - var now_uSec = Date.now() * 1000; - s.range = [now_uSec - 20*1000000, now_uSec]; - s.sanitize(); + yield promiseUpdatePluginBindings(gTestBrowser); - ok(stored(["bar.com","qux.com"]), "Data stored for sites"); - ok(!stored(["foo.com"]), "Data cleared for foo.com"); - ok(!stored(["baz.com"]), "Data cleared for baz.com"); + ok(stored(["foo.com","bar.com","baz.com","qux.com"]), + "Data stored for sites"); - // Clear everything - s.range = null; - s.sanitize(); + // Clear 20 seconds ago + let now_uSec = Date.now() * 1000; + sanitizer.range = [now_uSec - 20*1000000, now_uSec]; + sanitizer.sanitize(); - ok(!stored(null), "All data cleared"); + ok(stored(["bar.com","qux.com"]), "Data stored for sites"); + ok(!stored(["foo.com"]), "Data cleared for foo.com"); + ok(!stored(["baz.com"]), "Data cleared for baz.com"); - gBrowser.removeCurrentTab(); + // Clear everything + sanitizer.range = null; + sanitizer.sanitize(); - executeSoon(test_without_age); - }); - }, true); - content.location = testURL1; -} + ok(!stored(null), "All data cleared"); -function test_without_age() -{ + gBrowser.removeCurrentTab(); + gTestBrowser = null; +}); + +add_task(function* () { // Load page to set data for the plugin. gBrowser.selectedTab = gBrowser.addTab(); - gBrowser.selectedBrowser.addEventListener("load", function () { - gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); + gTestBrowser = gBrowser.selectedBrowser; - setFinishedCallback(function() { - ok(stored(["foo.com","bar.com","baz.com","qux.com"]), - "Data stored for sites"); + yield promiseTabLoadEvent(gBrowser.selectedTab, testURL2); - // Attempt to clear 20 seconds ago. The plugin will throw - // NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED, which should result in us - // clearing all data regardless of age. - var now_uSec = Date.now() * 1000; - s.range = [now_uSec - 20*1000000, now_uSec]; - s.sanitize(); + yield promiseUpdatePluginBindings(gTestBrowser); - ok(!stored(null), "All data cleared"); + ok(stored(["foo.com","bar.com","baz.com","qux.com"]), + "Data stored for sites"); - gBrowser.removeCurrentTab(); + // Attempt to clear 20 seconds ago. The plugin will throw + // NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED, which should result in us + // clearing all data regardless of age. + let now_uSec = Date.now() * 1000; + sanitizer.range = [now_uSec - 20*1000000, now_uSec]; + sanitizer.sanitize(); - executeSoon(finish); - }); - }, true); - content.location = testURL2; -} + ok(!stored(null), "All data cleared"); + + gBrowser.removeCurrentTab(); + gTestBrowser = null; +}); diff --git a/browser/base/content/test/plugins/browser_clearplugindata_noage.html b/browser/base/content/test/plugins/browser_clearplugindata_noage.html index 75e1f2e1f555..82097954120a 100644 --- a/browser/base/content/test/plugins/browser_clearplugindata_noage.html +++ b/browser/base/content/test/plugins/browser_clearplugindata_noage.html @@ -21,8 +21,6 @@ "baz.com:1:5," + "qux.com:1:100" ); - - setTimeout(testFinishedCallback, 0); } diff --git a/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js b/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js index 10c90d69c38f..9bbc4a1fe3e8 100644 --- a/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js +++ b/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js @@ -1,7 +1,3 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - /** * Test that plugin crash submissions still work properly after * click-to-play activation. diff --git a/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js index ac7ec5581166..a71f6ff9abe2 100644 --- a/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js +++ b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js @@ -1,9 +1,4 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - Cu.import("resource://gre/modules/CrashSubmit.jsm", this); -Cu.import("resource://gre/modules/Services.jsm"); const CRASH_URL = "http://example.com/browser/browser/base/content/test/plugins/plugin_crashCommentAndURL.html"; const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs"; diff --git a/browser/base/content/test/plugins/browser_plugin_infolink.js b/browser/base/content/test/plugins/browser_plugin_infolink.js new file mode 100644 index 000000000000..a0472c28a528 --- /dev/null +++ b/browser/base/content/test/plugins/browser_plugin_infolink.js @@ -0,0 +1,77 @@ +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); +let gTestBrowser = null; + +add_task(function* () { + registerCleanupFunction(function () { + clearAllPluginPermissions(); + Services.prefs.clearUserPref("plugins.click_to_play"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + gTestBrowser = null; + gBrowser.removeCurrentTab(); + window.focus(); + }); +}); + +add_task(function* () { + gBrowser.selectedTab = gBrowser.addTab(); + gTestBrowser = gBrowser.selectedBrowser; + + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.setBoolPref("plugins.click_to_play", true); + + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_DISABLED, "Test Plug-in"); + + // Prime the blocklist service, the remote service doesn't launch on startup. + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,"); + let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser); + ok(!exmsg, "exception: " + exmsg); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); +}); + +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + yield promiseUpdatePluginBindings(gTestBrowser); + + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED, + "Test 1a, plugin fallback type should be PLUGIN_DISABLED"); + + // This test opens a new tab to about:addons + let promise = waitForEvent(gBrowser.tabContainer, "TabOpen", null, true); + let success = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let pluginNode = content.document.getElementById("test"); + let manageLink = content.document.getAnonymousElementByAttribute(pluginNode, "anonid", "managePluginsLink"); + let bounds = manageLink.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + return true; + }); + ok(success, "click on manage link"); + yield promise; + + promise = waitForEvent(gBrowser.tabContainer, "TabClose", null, true); + + // in-process page, no cpows here + let condition = function() { + let win = gBrowser.selectedBrowser.contentWindow; + if (!!win && !!win.wrappedJSObject && !!win.wrappedJSObject.gViewController) { + return win.wrappedJSObject.gViewController.currentViewId == "addons://list/plugin"; + } + return false; + } + + yield promiseForCondition(condition, "Waited too long for about:addons to display.", 40, 500); + + // remove the tab containing about:addons + gBrowser.removeCurrentTab(); + + yield promise; +}); + diff --git a/browser/base/content/test/plugins/browser_plugin_reloading.js b/browser/base/content/test/plugins/browser_plugin_reloading.js new file mode 100644 index 000000000000..8b0158cdbc9b --- /dev/null +++ b/browser/base/content/test/plugins/browser_plugin_reloading.js @@ -0,0 +1,85 @@ +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); +let gTestBrowser = null; + +function updateAllTestPlugins(aState) { + setTestPluginEnabledState(aState, "Test Plug-in"); + setTestPluginEnabledState(aState, "Second Test Plug-in"); +} + +add_task(function* () { + registerCleanupFunction(Task.async(function*() { + clearAllPluginPermissions(); + Services.prefs.clearUserPref("plugins.click_to_play"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + resetBlocklist(); + gTestBrowser = null; + gBrowser.removeCurrentTab(); + window.focus(); + })); +}); + +add_task(function* () { + gBrowser.selectedTab = gBrowser.addTab(); + gTestBrowser = gBrowser.selectedBrowser; + + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.setBoolPref("plugins.click_to_play", true); + + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + // Prime the blocklist service, the remote service doesn't launch on startup. + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,"); + let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser); + ok(!exmsg, "exception: " + exmsg); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); +}); + +// Tests that a click-to-play plugin retains its activated state upon reloading +add_task(function* () { + clearAllPluginPermissions(); + + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 1, Should have a click-to-play notification"); + + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, + "Test 2, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); + + // run the plugin + yield promisePlayObject("test"); + + yield promiseUpdatePluginBindings(gTestBrowser); + + pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 3, plugin should have started"); + ok(pluginInfo.activated, "Test 4, plugin node should not be activated"); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let plugin = content.document.getElementById("test"); + let npobj1 = Components.utils.waiveXrays(plugin).getObjectValue(); + plugin.src = plugin.src; + let pluginsDiffer = false; + try { + Components.utils.waiveXrays(plugin).checkObjectValue(npobj1); + } catch (e) { + pluginsDiffer = true; + } + return pluginsDiffer; + }); + ok(result, "Test 5, plugins differ."); + + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 6, Plugin should have retained activated state."); + is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 7, plugin should have started"); +}); diff --git a/browser/base/content/test/plugins/browser_pluginnotification.js b/browser/base/content/test/plugins/browser_pluginnotification.js index 40d1c316aeee..29c3c51f694b 100644 --- a/browser/base/content/test/plugins/browser_pluginnotification.js +++ b/browser/base/content/test/plugins/browser_pluginnotification.js @@ -1,589 +1,387 @@ -var rootDir = getRootDirectory(gTestPath); -const gTestRoot = rootDir; -const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); +let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); +let gTestBrowser = null; -var gTestBrowser = null; -var gNextTest = null; -var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); - -Components.utils.import("resource://gre/modules/Services.jsm"); - -// This listens for the next opened tab and checks it is of the right url. -// opencallback is called when the new tab is fully loaded -// closecallback is called when the tab is closed -function TabOpenListener(url, opencallback, closecallback) { - this.url = url; - this.opencallback = opencallback; - this.closecallback = closecallback; - - gBrowser.tabContainer.addEventListener("TabOpen", this, false); +function updateAllTestPlugins(aState) { + setTestPluginEnabledState(aState, "Test Plug-in"); + setTestPluginEnabledState(aState, "Second Test Plug-in"); } -TabOpenListener.prototype = { - url: null, - opencallback: null, - closecallback: null, - tab: null, - browser: null, - - handleEvent: function(event) { - if (event.type == "TabOpen") { - gBrowser.tabContainer.removeEventListener("TabOpen", this, false); - this.tab = event.originalTarget; - this.browser = this.tab.linkedBrowser; - gBrowser.addEventListener("pageshow", this, false); - } else if (event.type == "pageshow") { - if (event.target.location.href != this.url) - return; - gBrowser.removeEventListener("pageshow", this, false); - this.tab.addEventListener("TabClose", this, false); - var url = this.browser.contentDocument.location.href; - is(url, this.url, "Should have opened the correct tab"); - this.opencallback(this.tab, this.browser.contentWindow); - } else if (event.type == "TabClose") { - if (event.originalTarget != this.tab) - return; - this.tab.removeEventListener("TabClose", this, false); - this.opencallback = null; - this.tab = null; - this.browser = null; - // Let the window close complete - executeSoon(this.closecallback); - this.closecallback = null; - } - } -}; - -function test() { - waitForExplicitFinish(); - SimpleTest.requestCompleteLog(); - requestLongerTimeout(2); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(Task.async(function*() { clearAllPluginPermissions(); - Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); - return new Promise(resolve => { - setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", resolve); - }); - }); - Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.clearUserPref("plugins.click_to_play"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + resetBlocklist(); + gTestBrowser = null; + gBrowser.removeCurrentTab(); + window.focus(); + })); +}); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); - - var newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; +add_task(function* () { + gBrowser.selectedTab = gBrowser.addTab(); gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - prepareTest(runAfterPluginBindingAttached(test1a), gTestRoot + "plugin_unknown.html"); -} -function finishTest() { - clearAllPluginPermissions(); - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.setBoolPref("plugins.click_to_play", true); -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} + // Prime the blocklist service, the remote service doesn't launch on startup. + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,"); + let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser); + ok(!exmsg, "exception: " + exmsg); -// Due to layout being async, "PluginBindAttached" may trigger later. -// This wraps a function to force a layout flush, thus triggering it, -// and schedules the function execution so they're definitely executed -// afterwards. -function runAfterPluginBindingAttached(func) { - return function() { - let doc = gTestBrowser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(func); - }; -} + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); +}); // Tests a page with an unknown plugin in it. -function test1a() { - var pluginNode = gTestBrowser.contentDocument.getElementById("unknown"); - ok(pluginNode, "Test 1a, Found plugin in page"); - var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED, "Test 1a, plugin fallback type should be PLUGIN_UNSUPPORTED"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_unknown.html"); - prepareTest(runAfterPluginBindingAttached(test1b), gTestRoot + "plugin_unknown.html"); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + let pluginInfo = yield promiseForPluginInfo("unknown"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED, + "Test 1a, plugin fallback type should be PLUGIN_UNSUPPORTED"); +}); -function test1b() { - var plugin = getTestPlugin(); - ok(plugin, "Test 1b, Should have a test plugin"); - plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED; - prepareTest(runAfterPluginBindingAttached(test2), gTestRoot + "plugin_test.html"); -} +// Tests that going back will reshow the notification for click-to-play plugins +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); -// Tests a page with a working plugin in it. -function test2() { - var plugin = getTestPlugin(); - ok(plugin, "Should have a test plugin"); - plugin.enabledState = Ci.nsIPluginTag.STATE_DISABLED; - prepareTest(runAfterPluginBindingAttached(test3), gTestRoot + "plugin_test.html"); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); -// Tests a page with a disabled plugin in it. -function test3() { - new TabOpenListener("about:addons", test4, prepareTest5); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); - var pluginNode = gTestBrowser.contentDocument.getElementById("test"); - ok(pluginNode, "Test 3, Found plugin in page"); - var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED, "Test 3, plugin fallback type should be PLUGIN_DISABLED"); - var manageLink = gTestBrowser.contentDocument.getAnonymousElementByAttribute(pluginNode, "anonid", "managePluginsLink"); - ok(manageLink, "Test 3, found 'manage' link in plugin-problem binding"); + yield promisePopupNotification("click-to-play-plugins"); - EventUtils.synthesizeMouseAtCenter(manageLink, {}, gTestBrowser.contentWindow); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,hi"); -function test4(tab, win) { - is(win.wrappedJSObject.gViewController.currentViewId, "addons://list/plugin", "Test 4, Should have displayed the plugins pane"); - gBrowser.removeTab(tab); -} + // make sure the notification is gone + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!notification, "Test 11b, Should not have a click-to-play notification"); -function prepareTest5() { - info("prepareTest5"); - var plugin = getTestPlugin(); - plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED; - setAndUpdateBlocklist(gHttpTestRoot + "blockPluginHard.xml", - function() { - info("prepareTest5 callback"); - prepareTest(runAfterPluginBindingAttached(test5), gTestRoot + "plugin_test.html"); - }); -} - -// Tests a page with a blocked plugin in it. -function test5() { - info("test5"); - let notification = PopupNotifications.getNotification("click-to-play-plugins"); - ok(notification, "Test 5: There should be a plugin notification for blocked plugins"); - ok(notification.dismissed, "Test 5: The plugin notification should be dismissed by default"); - - notification.reshow(); - is(notification.options.pluginData.size, 1, "Test 5: Only the blocked plugin should be present in the notification"); - ok(PopupNotifications.panel.firstChild._buttonContainer.hidden, "Part 5: The blocked plugins notification should not have any buttons visible."); - - var pluginNode = gTestBrowser.contentDocument.getElementById("test"); - ok(pluginNode, "Test 5, Found plugin in page"); - var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED, "Test 5, plugin fallback type should be PLUGIN_BLOCKLISTED"); - - prepareTest(runAfterPluginBindingAttached(test6), gTestRoot + "plugin_both.html"); -} - -// Tests a page with a blocked and unknown plugin in it. -function test6() { - prepareTest(runAfterPluginBindingAttached(test7), gTestRoot + "plugin_both2.html"); -} - -// Tests a page with a blocked and unknown plugin in it (alternate order to above). -function test7() { - var plugin = getTestPlugin(); - plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY; - getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY; - - setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", function() { - prepareTest(runAfterPluginBindingAttached(test8), gTestRoot + "plugin_test.html"); - }); -} - -// Tests a page with a working plugin that is click-to-play -function test8() { - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 8, Should have a click-to-play notification"); - - var pluginNode = gTestBrowser.contentDocument.getElementById("test"); - ok(pluginNode, "Test 8, Found plugin in page"); - var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 8, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); - - prepareTest(runAfterPluginBindingAttached(test11a), gTestRoot + "plugin_test3.html"); -} - -// Tests 9 & 10 removed - -// Tests that the going back will reshow the notification for click-to-play plugins (part 1/4) -function test11a() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 11a, Should have a click-to-play notification"); - - prepareTest(test11b, "about:blank"); -} - -// Tests that the going back will reshow the notification for click-to-play plugins (part 2/4) -function test11b() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(!popupNotification, "Test 11b, Should not have a click-to-play notification"); - - Services.obs.addObserver(test11c, "PopupNotifications-updateNotShowing", false); gTestBrowser.contentWindow.history.back(); -} -// Tests that the going back will reshow the notification for click-to-play plugins (part 3/4) -function test11c() { - Services.obs.removeObserver(test11c, "PopupNotifications-updateNotShowing"); - var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - waitForCondition(condition, test11d, "Test 11c, waited too long for click-to-play-plugin notification"); -} - -// Tests that the going back will reshow the notification for click-to-play plugins (part 4/4) -function test11d() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 11d, Should have a click-to-play notification"); - - prepareTest(runAfterPluginBindingAttached(test12a), gHttpTestRoot + "plugin_clickToPlayAllow.html"); -} + yield promisePopupNotification("click-to-play-plugins"); +}); // Tests that the "Allow Always" permission works for click-to-play plugins -function test12a() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 12a, Should have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 12a, Plugin should not be activated"); +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + yield promisePopupNotification("click-to-play-plugins"); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 12a, Plugin should not be activated"); // Simulate clicking the "Allow Always" button. - popupNotification.reshow(); + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + + yield promiseForNotificationShown(notification); + PopupNotifications.panel.firstChild._primaryButton.click(); - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test12b, "Test 12a, Waited too long for plugin to activate"); -} - -function test12b() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 12d, Should have a click-to-play notification"); - prepareTest(runAfterPluginBindingAttached(test12c), gHttpTestRoot + "plugin_two_types.html"); -} + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 12a, Plugin should be activated"); +}); // Test that the "Always" permission, when set for just the Test plugin, // does not also allow the Second Test plugin. -function test12c() { - var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "Test 12d, Should have a click-to-play notification"); - var test = gTestBrowser.contentDocument.getElementById("test"); - var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA"); - var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB"); - ok(test.activated, "Test 12d, Test plugin should be activated"); - ok(!secondtestA.activated, "Test 12d, Second Test plugin (A) should not be activated"); - ok(!secondtestB.activated, "Test 12d, Second Test plugin (B) should not be activated"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + yield promisePopupNotification("click-to-play-plugins"); + + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let test = content.document.getElementById("test"); + let secondtestA = content.document.getElementById("secondtestA"); + let secondtestB = content.document.getElementById("secondtestB"); + return test.activated && !secondtestA.activated && !secondtestB.activated; + }); + ok(result, "Content plugins are set up"); clearAllPluginPermissions(); - var plugin = getTestPlugin(); - plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED; - prepareTest(test14, gTestRoot + "plugin_test2.html"); -} +}); -// Test 13 removed +// Tests that the plugin's "activated" property is true for working plugins +// with click-to-play disabled. +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_ENABLED); -// Tests that the plugin's "activated" property is true for working plugins with click-to-play disabled. -function test14() { - var plugin = gTestBrowser.contentDocument.getElementById("test1"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 14, Plugin should be activated"); + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test2.html"); - var plugin = getTestPlugin(); - plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY; - getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY; - prepareTest(runAfterPluginBindingAttached(test15), gTestRoot + "plugin_alternate_content.html"); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let pluginInfo = yield promiseForPluginInfo("test1"); + ok(pluginInfo.activated, "Test 14, Plugin should be activated"); +}); // Tests that the overlay is shown instead of alternate content when -// plugins are click to play -function test15() { - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var doc = gTestBrowser.contentDocument; - var mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(mainBox, "Test 15, Plugin with id=" + plugin.id + " overlay should exist"); +// plugins are click to play. +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - prepareTest(runAfterPluginBindingAttached(test17), gTestRoot + "plugin_bug749455.html"); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_alternate_content.html"); -// Test 16 removed + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return !!mainBox; + }); + ok(result, "Test 15, Plugin overlay should exist"); +}); // Tests that mContentType is used for click-to-play plugins, and not the // inspected type. -function test17() { - var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(clickToPlayNotification, "Test 17, Should have a click-to-play notification"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_bug749455.html"); - setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml", - function() { - prepareTest(runAfterPluginBindingAttached(test18a), gHttpTestRoot + "plugin_test.html"); - }); -} + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -// Tests a vulnerable, updatable plugin -function test18a() { - var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(clickToPlayNotification, "Test 18a, Should have a click-to-play notification"); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - ok(plugin, "Test 18a, Found plugin in page"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "Test 18a, plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE"); - ok(!objLoadingContent.activated, "Test 18a, Plugin should not be activated"); - var overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay.classList.contains("visible"), "Test 18a, Plugin overlay should exist, not be hidden"); - var updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink"); - ok(updateLink.style.visibility != "hidden", "Test 18a, Plugin should have an update link"); - - var pluginUpdateURL = Services.urlFormatter.formatURLPref("plugins.update.url"); - var tabOpenListener = new TabOpenListener(pluginUpdateURL, function(tab) { - gBrowser.removeTab(tab); - }, test18b); - EventUtils.synthesizeMouseAtCenter(updateLink, {}, gTestBrowser.contentWindow); -} - -function test18b() { - // clicking the update link should not activate the plugin - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 18b, Plugin should not be activated"); - var overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay.classList.contains("visible"), "Test 18b, Plugin overlay should exist, not be hidden"); - - setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableNoUpdate.xml", - function() { - prepareTest(runAfterPluginBindingAttached(test18c), gHttpTestRoot + "plugin_test.html"); - }); -} - -// Tests a vulnerable plugin with no update -function test18c() { - var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(clickToPlayNotification, "Test 18c, Should have a click-to-play notification"); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - ok(plugin, "Test 18c, Found plugin in page"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE, "Test 18c, plugin fallback type should be PLUGIN_VULNERABLE_NO_UPDATE"); - ok(!objLoadingContent.activated, "Test 18c, Plugin should not be activated"); - var overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(overlay.classList.contains("visible"), "Test 18c, Plugin overlay should exist, not be hidden"); - var updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink"); - ok(updateLink.style.display != "block", "Test 18c, Plugin should not have an update link"); - - // check that click "Always allow" works with blocklisted plugins - clickToPlayNotification.reshow(); - PopupNotifications.panel.firstChild._primaryButton.click(); - - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test18d, "Test 18d, Waited too long for plugin to activate"); -} - -// continue testing "Always allow" -function test18d() { - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 18d, Plugin should be activated"); - - prepareTest(test18e, gHttpTestRoot + "plugin_test.html"); -} - -// continue testing "Always allow" -function test18e() { - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 18e, Plugin should be activated"); - - clearAllPluginPermissions(); - prepareTest(runAfterPluginBindingAttached(test18f), gHttpTestRoot + "plugin_test.html"); -} - -// clicking the in-content overlay of a vulnerable plugin should bring -// up the notification and not directly activate the plugin -function test18f() { - var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(notification, "Test 18f, Should have a click-to-play notification"); - ok(notification.dismissed, "Test 18f, notification should start dismissed"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 18f, Plugin should not be activated"); - - var oldEventCallback = notification.options.eventCallback; - notification.options.eventCallback = function() { - oldEventCallback(); - executeSoon(test18g); - }; - EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow); -} - -function test18g() { - var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(notification, "Test 18g, Should have a click-to-play notification"); - ok(!notification.dismissed, "Test 18g, notification should be open"); - notification.options.eventCallback = null; - var plugin = gTestBrowser.contentDocument.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 18g, Plugin should not be activated"); - - setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", - function() { - resetBlocklist(); - prepareTest(runAfterPluginBindingAttached(test19a), gTestRoot + "plugin_test.html"); - }); -} + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 17, Should have a click-to-play notification"); +}); // Tests that clicking the icon of the overlay activates the doorhanger -function test19a() { - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 19a, Plugin should not be activated"); - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 19a, Doorhanger should start out dismissed"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated"); + + ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, + "Test 19a, Doorhanger should start out dismissed"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let icon = doc.getAnonymousElementByAttribute(plugin, "class", "icon"); + let bounds = icon.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); - var icon = doc.getAnonymousElementByAttribute(plugin, "class", "icon"); - EventUtils.synthesizeMouseAtCenter(icon, {}, gTestBrowser.contentWindow); let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed; - waitForCondition(condition, test19b, "Test 19a, Waited too long for doorhanger to activate"); -} - -function test19b() { - prepareTest(runAfterPluginBindingAttached(test19c), gTestRoot + "plugin_test.html"); -} + yield promiseForCondition(condition); +}); // Tests that clicking the text of the overlay activates the plugin -function test19c() { - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 19c, Plugin should not be activated"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 19c, Doorhanger should start out dismissed"); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated"); + + ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, + "Test 19c, Doorhanger should start out dismissed"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let text = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay"); + let bounds = text.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); - var text = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay"); - EventUtils.synthesizeMouseAtCenter(text, {}, gTestBrowser.contentWindow); let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed; - waitForCondition(condition, test19d, "Test 19c, Waited too long for doorhanger to activate"); -} - -function test19d() { - prepareTest(runAfterPluginBindingAttached(test19e), gTestRoot + "plugin_test.html"); -} + yield promiseForCondition(condition); +}); // Tests that clicking the box of the overlay activates the doorhanger // (just to be thorough) -function test19e() { - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 19e, Plugin should not be activated"); +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 19e, Doorhanger should start out dismissed"); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); - EventUtils.synthesizeMouse(plugin, 50, 50, {}, gTestBrowser.contentWindow); - let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed; - waitForCondition(condition, test19f, "Test 19e, Waited too long for plugin to activate"); -} + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated"); -function test19f() { - prepareTest(test20a, gTestRoot + "plugin_hidden_to_visible.html"); -} + ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, + "Test 19e, Doorhanger should start out dismissed"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", 50, 50, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", 50, 50, 0, 1, 0, false, 0, 0); + }); + + let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed && + PopupNotifications.panel.firstChild; + yield promiseForCondition(condition); + PopupNotifications.panel.firstChild._primaryButton.click(); + + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 19e, Plugin should not be activated"); + + clearAllPluginPermissions(); +}); // Tests that a plugin in a div that goes from style="display: none" to // "display: block" can be clicked to activate. -function test20a() { - var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(!clickToPlayNotification, "Test 20a, Should not have a click-to-play notification"); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("plugin"); - var mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); - ok(mainBox, "Test 20a, plugin overlay should not be null"); - var pluginRect = mainBox.getBoundingClientRect(); - ok(pluginRect.width == 0, "Test 20a, plugin should have an overlay with 0px width"); - ok(pluginRect.height == 0, "Test 20a, plugin should have an overlay with 0px height"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 20a, plugin should not be activated"); - var div = doc.getElementById("container"); - ok(div.style.display == "none", "Test 20a, container div should be display: none"); +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - div.style.display = "block"; - var condition = function() { - var pluginRect = mainBox.getBoundingClientRect(); - return (pluginRect.width == 200); - } - waitForCondition(condition, test20b, "Test 20a, Waited too long for plugin to become visible"); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_hidden_to_visible.html"); -function test20b() { - var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(clickToPlayNotification, "Test 20b, Should now have a click-to-play notification"); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("plugin"); - var pluginRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); - ok(pluginRect.width == 200, "Test 20b, plugin should have an overlay with 200px width"); - ok(pluginRect.height == 200, "Test 20b, plugin should have an overlay with 200px height"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 20b, plugin should not be activated"); + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 20b, Doorhanger should start out dismissed"); + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 20a, Should have a click-to-play notification"); - EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow); - let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed; - waitForCondition(condition, test20c, "Test 20b, Waited too long for plugin to activate"); -} + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + return !!overlay; + }); + ok(result, "Test 20a, Plugin overlay should exist"); -function test20c() { + result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + let overlayRect = mainBox.getBoundingClientRect(); + return overlayRect.width == 0 && overlayRect.height == 0; + }); + ok(result, "Test 20a, plugin should have an overlay with 0px width and height"); + + let pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 20b, plugin should not be activated"); + + result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let div = doc.getElementById("container"); + return div.style.display == "none"; + }); + ok(result, "Test 20b, container div should be display: none"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let div = doc.getElementById("container"); + div.style.display = "block"; + }); + + result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + let overlayRect = mainBox.getBoundingClientRect(); + return overlayRect.width == 200 && overlayRect.height == 200; + }); + ok(result, "Test 20b, Waited too long for plugin to become visible"); + + pluginInfo = yield promiseForPluginInfo("test"); + ok(!pluginInfo.activated, "Test 20b, plugin should not be activated"); + + ok(notification.dismissed, "Test 20c, Doorhanger should start out dismissed"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let bounds = plugin.getBoundingClientRect(); + let left = (bounds.left + bounds.right) / 2; + let top = (bounds.top + bounds.bottom) / 2; + let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); + }); + + let condition = function() !notification.dismissed && !!PopupNotifications.panel.firstChild; + yield promiseForCondition(condition); PopupNotifications.panel.firstChild._primaryButton.click(); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("plugin"); - let condition = function() plugin.activated; - waitForCondition(condition, test20d, "Test 20c", "Waiting for plugin to activate"); -} -function test20d() { - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("plugin"); - var pluginRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); - ok(pluginRect.width == 0, "Test 20d, plugin should have click-to-play overlay with zero width"); - ok(pluginRect.height == 0, "Test 20d, plugin should have click-to-play overlay with zero height"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 20d, plugin should be activated"); + pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 20c, plugin should be activated"); + + result = ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); + return overlayRect.width == 0 && overlayRect.height == 0; + }); + ok(result, "Test 20c, plugin should have overlay dims of 200px"); clearAllPluginPermissions(); - - prepareTest(runAfterPluginBindingAttached(test21a), gTestRoot + "plugin_two_types.html"); -} +}); // Test having multiple different types of plugin on one page -function test21a() { - var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); +add_task(function* () { + // contains three plugins, application/x-test, application/x-second-test x 2 + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); ok(notification, "Test 21a, Should have a click-to-play notification"); - var doc = gTestBrowser.contentDocument; - var ids = ["test", "secondtestA", "secondtestB"]; - for (var id of ids) { - var plugin = doc.getElementById(id); - var rect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); - ok(rect.width == 200, "Test 21a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being clicked"); - ok(rect.height == 200, "Test 21a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being clicked"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 21a, Plugin with id=" + plugin.id + " should not be activated"); + // confirm all three are blocked by ctp at this point + let ids = ["test", "secondtestA", "secondtestB"]; + for (let id of ids) { + let result = yield ContentTask.spawn(gTestBrowser, {aId: id}, function* () { + let doc = content.document; + let plugin = doc.getElementById(arguments[0].aId); + let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); + return overlayRect.width == 200 && overlayRect.height == 200; + }); + ok(result, "Test 21a, plugin " + id + " should have click-to-play overlay with dims"); + + let pluginInfo = yield promiseForPluginInfo(id); + ok(!pluginInfo.activated, "Test 21a, Plugin with id=" + id + " should not be activated"); } + notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 21a, Should have a click-to-play notification"); + // we have to actually show the panel to get the bindings to instantiate - notification.reshow(); + yield promiseForNotificationShown(notification); + is(notification.options.pluginData.size, 2, "Test 21a, Should have two types of plugin in the notification"); - var centerAction = null; - for (var action of notification.options.pluginData.values()) { + let centerAction = null; + for (let action of notification.options.pluginData.values()) { if (action.pluginName == "Test") { centerAction = action; break; @@ -591,8 +389,8 @@ function test21a() { } ok(centerAction, "Test 21b, found center action for the Test plugin"); - var centerItem = null; - for (var item of PopupNotifications.panel.firstChild.childNodes) { + let centerItem = null; + for (let item of PopupNotifications.panel.firstChild.childNodes) { is(item.value, "block", "Test 21b, all plugins should start out blocked"); if (item.action == centerAction) { centerItem = item; @@ -601,44 +399,46 @@ function test21a() { } ok(centerItem, "Test 21b, found center item for the Test plugin"); - // "click" the button to activate the Test plugin + // Select the allow now option in the select drop down for Test Plugin centerItem.value = "allownow"; + + // "click" the button to activate the Test plugin PopupNotifications.panel.firstChild._primaryButton.click(); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test21c, "Test 21b, Waited too long for plugin to activate"); -} + let pluginInfo = yield promiseForPluginInfo("test"); + ok(pluginInfo.activated, "Test 21b, plugin should be activated"); -function test21c() { - var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(notification, "Test 21c, Should have a click-to-play notification"); + notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 21b, Should have a click-to-play notification"); + + yield promiseForNotificationShown(notification); - notification.reshow(); ok(notification.options.pluginData.size == 2, "Test 21c, Should have one type of plugin in the notification"); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("test"); - var rect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); - ok(rect.width == 0, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 0px width after being clicked"); - ok(rect.height == 0, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 0px height after being clicked"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 21c, Plugin with id=" + plugin.id + " should be activated"); + let result = ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); + return overlayRect.width == 0 && overlayRect.height == 0; + }); + ok(result, "Test 21c, plugin should have overlay dims of 0px"); - var ids = ["secondtestA", "secondtestB"]; - for (var id of ids) { - var plugin = doc.getElementById(id); - var rect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); - ok(rect.width == 200, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being clicked"); - ok(rect.height == 200, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being clicked"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(!objLoadingContent.activated, "Test 21c, Plugin with id=" + plugin.id + " should not be activated"); + ids = ["secondtestA", "secondtestB"]; + for (let id of ids) { + let result = yield ContentTask.spawn(gTestBrowser, {aId: id}, function* () { + let doc = content.document; + let plugin = doc.getElementById(arguments[0].aId); + let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); + return overlayRect.width == 200 && overlayRect.height == 200; + }); + ok(result, "Test 21c, plugin " + id + " should have click-to-play overlay with zero dims"); + + let pluginInfo = yield promiseForPluginInfo(id); + ok(!pluginInfo.activated, "Test 21c, Plugin with id=" + id + " should not be activated"); } - var centerAction = null; - for (var action of notification.options.pluginData.values()) { + centerAction = null; + for (let action of notification.options.pluginData.values()) { if (action.pluginName == "Second Test") { centerAction = action; break; @@ -646,8 +446,8 @@ function test21c() { } ok(centerAction, "Test 21d, found center action for the Second Test plugin"); - var centerItem = null; - for (var item of PopupNotifications.panel.firstChild.childNodes) { + centerItem = null; + for (let item of PopupNotifications.panel.firstChild.childNodes) { if (item.action == centerAction) { is(item.value, "block", "Test 21d, test plugin 2 should start blocked"); centerItem = item; @@ -659,211 +459,120 @@ function test21c() { } ok(centerItem, "Test 21d, found center item for the Second Test plugin"); - // "click" the button to activate the Second Test plugins + // Select the allow now option in the select drop down for Second Test Plguins centerItem.value = "allownow"; + + // "click" the button to activate the Second Test plugins PopupNotifications.panel.firstChild._primaryButton.click(); - var doc = gTestBrowser.contentDocument; - var plugin = doc.getElementById("secondtestA"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - var condition = function() objLoadingContent.activated; - waitForCondition(condition, test21e, "Test 21d, Waited too long for plugin to activate"); -} + notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 21d, Should have a click-to-play notification"); -function test21e() { - var doc = gTestBrowser.contentDocument; - var ids = ["test", "secondtestA", "secondtestB"]; - for (var id of ids) { - var plugin = doc.getElementById(id); - var rect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); - ok(rect.width == 0, "Test 21e, Plugin with id=" + plugin.id + " overlay rect should have 0px width after being clicked"); - ok(rect.height == 0, "Test 21e, Plugin with id=" + plugin.id + " overlay rect should have 0px height after being clicked"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - ok(objLoadingContent.activated, "Test 21e, Plugin with id=" + plugin.id + " should be activated"); + ids = ["test", "secondtestA", "secondtestB"]; + for (let id of ids) { + let result = yield ContentTask.spawn(gTestBrowser, {aId: id}, function* () { + let doc = content.document; + let plugin = doc.getElementById(arguments[0].aId); + let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect(); + return overlayRect.width == 0 && overlayRect.height == 0; + }); + ok(result, "Test 21d, plugin " + id + " should have click-to-play overlay with zero dims"); + + let pluginInfo = yield promiseForPluginInfo(id); + ok(pluginInfo.activated, "Test 21d, Plugin with id=" + id + " should not be activated"); } - - getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY; - getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY; - - clearAllPluginPermissions(); - - prepareTest(runAfterPluginBindingAttached(test22), gTestRoot + "plugin_test.html"); -} - -// Tests that a click-to-play plugin retains its activated state upon reloading -function test22() { - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 22, Should have a click-to-play notification"); - - // Plugin should start as CTP - var pluginNode = gTestBrowser.contentDocument.getElementById("test"); - ok(pluginNode, "Test 22, Found plugin in page"); - var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 22, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); - - // Activate - objLoadingContent.playPlugin(); - is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 22, plugin should have started"); - ok(pluginNode.activated, "Test 22, plugin should be activated"); - - // Spin event loop for plugin to finish spawning - executeSoon(function() { - var oldVal = pluginNode.getObjectValue(); - pluginNode.src = pluginNode.src; - is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 22, Plugin should have retained activated state"); - ok(pluginNode.activated, "Test 22, plugin should have remained activated"); - // Sanity, ensure that we actually reloaded the instance, since this behavior might change in the future. - var pluginsDiffer; - try { - pluginNode.checkObjectValue(oldVal); - } catch (e) { - pluginsDiffer = true; - } - ok(pluginsDiffer, "Test 22, plugin should have reloaded"); - - prepareTest(runAfterPluginBindingAttached(test23), gTestRoot + "plugin_test.html"); - }); -} +}); // Tests that a click-to-play plugin resets its activated state when changing types -function test23() { - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 23, Should have a click-to-play notification"); +add_task(function* () { + clearAllPluginPermissions(); + + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 22, Should have a click-to-play notification"); // Plugin should start as CTP - var pluginNode = gTestBrowser.contentDocument.getElementById("test"); - ok(pluginNode, "Test 23, Found plugin in page"); - var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, + "Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); - // Activate - objLoadingContent.playPlugin(); - is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 23, plugin should have started"); - ok(pluginNode.activated, "Test 23, plugin should be activated"); + yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + plugin.type = null; + // We currently don't properly change state just on type change, + // so rebind the plugin to tree. bug 767631 + plugin.parentNode.appendChild(plugin); + }); - // Reload plugin (this may need RunSoon() in the future when plugins change state asynchronously) - pluginNode.type = null; - // We currently don't properly change state just on type change, - // so rebind the plugin to tree. bug 767631 - pluginNode.parentNode.appendChild(pluginNode); - is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, plugin should be unloaded"); - pluginNode.type = "application/x-test"; - pluginNode.parentNode.appendChild(pluginNode); - is(objLoadingContent.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, Plugin should not have activated"); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 23, Plugin should be click-to-play"); - ok(!pluginNode.activated, "Test 23, plugin node should not be activated"); + pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, plugin should be TYPE_NULL"); - prepareTest(runAfterPluginBindingAttached(test24a), gHttpTestRoot + "plugin_test.html"); -} + let result = yield ContentTask.spawn(gTestBrowser, {}, function* () { + let doc = content.document; + let plugin = doc.getElementById("test"); + plugin.type = "application/x-test"; + plugin.parentNode.appendChild(plugin); + }); -// Test that "always allow"-ing a plugin will not allow it when it becomes -// blocklisted. -function test24a() { - var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(notification, "Test 24a, Should have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(plugin, "Test 24a, Found plugin in page"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 24a, Plugin should be click-to-play"); - ok(!objLoadingContent.activated, "Test 24a, plugin should not be activated"); + pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, plugin should be TYPE_NULL"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, + "Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY"); + ok(!pluginInfo.activated, "Test 23, plugin node should not be activated"); +}); - // simulate "always allow" - notification.reshow(); - PopupNotifications.panel.firstChild._primaryButton.click(); - waitForCondition(() => objLoadingContent.activated, () => { - prepareTest(test24b, gHttpTestRoot + "plugin_test.html"); - }, "Test 24a, plugin should now be activated."); +// Plugin sync removal test. Note this test produces a notification drop down since +// the plugin we add has zero dims. +add_task(function* () { + updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_syncRemoved.html"); -// did the "always allow" work as intended? -function test24b() { - var plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(plugin, "Test 24b, Found plugin in page"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - waitForCondition(() => objLoadingContent.activated, () => { - setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml", () => { - prepareTest(runAfterPluginBindingAttached(test24c), gHttpTestRoot + "plugin_test.html"); - }); - }, "Test 24b, plugin should be activated"); -} + // Maybe there some better trick here, we need to wait for the page load, then + // wait for the js to execute in the page. + yield waitForMs(500); -// the plugin is now blocklisted, so it should not automatically load -function test24c() { - var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(notification, "Test 24c, Should have a click-to-play notification"); - var plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(plugin, "Test 24c, Found plugin in page"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "Test 24c, Plugin should be vulnerable/updatable"); - waitForCondition(() => !objLoadingContent.activated, () => { - // simulate "always allow" - notification.reshow(); - PopupNotifications.panel.firstChild._primaryButton.click(); - - prepareTest(test24d, gHttpTestRoot + "plugin_test.html"); - }, "Test 24c, plugin should not be activated"); -} - -// We should still be able to always allow a plugin after we've seen that it's -// blocklisted. -function test24d() { - var plugin = gTestBrowser.contentDocument.getElementById("test"); - ok(plugin, "Test 24d, Found plugin in page"); - var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); - waitForCondition(() => objLoadingContent.activated, () => { - // this resets the vulnerable plugin permission - setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", () => { - clearAllPluginPermissions(); - resetBlocklist(); - prepareTest(test25, gTestRoot + "plugin_syncRemoved.html"); - }); - }, "Test 24d, plugin should be activated"); -} - -function test25() { let notification = PopupNotifications.getNotification("click-to-play-plugins"); ok(notification, "Test 25: There should be a plugin notification even if the plugin was immediately removed"); ok(notification.dismissed, "Test 25: The notification should be dismissed by default"); - prepareTest26(); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,hi"); +}); -function prepareTest26() { - info("prepareTest26"); - let plugin = getTestPlugin(); - plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED; - setAndUpdateBlocklist(gHttpTestRoot + "blockPluginInfoURL.xml", - function() { - info("prepareTest26 callback"); - prepareTest(runAfterPluginBindingAttached(test26), gTestRoot + "plugin_test.html"); - }); -} +// Tests a page with a blocked plugin in it and make sure the infoURL property +// the blocklist file gets used. +add_task(function* () { + clearAllPluginPermissions(); + + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginInfoURL.xml", gTestBrowser); + + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html"); + + // Work around for delayed PluginBindingAttached + yield promiseUpdatePluginBindings(gTestBrowser); -// Tests a page with a blocked plugin in it and make sure the -// infoURL property from the blocklist file gets used. -function test26() { - info("test26 - Test infoURL"); let notification = PopupNotifications.getNotification("click-to-play-plugins"); // Since the plugin notification is dismissed by default, reshow it. - notification.reshow(); + yield promiseForNotificationShown(notification); - let pluginNode = gTestBrowser.contentDocument.getElementById("test"); - ok(pluginNode, "Test 26, Found plugin in page"); - let objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent); - is(objLoadingContent.pluginFallbackType, - Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED, + let pluginInfo = yield promiseForPluginInfo("test"); + is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED, "Test 26, plugin fallback type should be PLUGIN_BLOCKLISTED"); + ok(!pluginInfo.activated, "Plugin should be activated."); const testUrl = "http://test.url.com/"; - let doc = gTestBrowser.contentDocument; let firstPanelChild = PopupNotifications.panel.firstChild; - - let infoLink = doc.getAnonymousElementByAttribute( - firstPanelChild, "anonid", "click-to-play-plugins-notification-link"); - + let infoLink = document.getAnonymousElementByAttribute(firstPanelChild, "anonid", + "click-to-play-plugins-notification-link"); is(infoLink.href, testUrl, "Test 26, the notification URL needs to match the infoURL from the blocklist file."); - - finishTest(); -} +}); diff --git a/browser/base/content/test/plugins/browser_pluginplaypreview.js b/browser/base/content/test/plugins/browser_pluginplaypreview.js index 49b7c63c1111..6691a4e12c78 100644 --- a/browser/base/content/test/plugins/browser_pluginplaypreview.js +++ b/browser/base/content/test/plugins/browser_pluginplaypreview.js @@ -1,7 +1,3 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - var rootDir = getRootDirectory(gTestPath); const gTestRoot = rootDir; diff --git a/browser/base/content/test/plugins/browser_pluginplaypreview2.js b/browser/base/content/test/plugins/browser_pluginplaypreview2.js index a5dc6b8da419..fadceeb01cad 100644 --- a/browser/base/content/test/plugins/browser_pluginplaypreview2.js +++ b/browser/base/content/test/plugins/browser_pluginplaypreview2.js @@ -1,7 +1,3 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - var rootDir = getRootDirectory(gTestPath); const gTestRoot = rootDir; diff --git a/browser/base/content/test/plugins/browser_pluginplaypreview3.js b/browser/base/content/test/plugins/browser_pluginplaypreview3.js index 0b0464c8f0ad..3f756b621ea4 100644 --- a/browser/base/content/test/plugins/browser_pluginplaypreview3.js +++ b/browser/base/content/test/plugins/browser_pluginplaypreview3.js @@ -1,7 +1,3 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - var rootDir = getRootDirectory(gTestPath); const gTestRoot = rootDir; diff --git a/browser/base/content/test/plugins/browser_plugins_added_dynamically.js b/browser/base/content/test/plugins/browser_plugins_added_dynamically.js index 20450d60de99..804979f5fd1f 100644 --- a/browser/base/content/test/plugins/browser_plugins_added_dynamically.js +++ b/browser/base/content/test/plugins/browser_plugins_added_dynamically.js @@ -1,178 +1,137 @@ var rootDir = getRootDirectory(gTestPath); const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/"); - -let gTestBrowser = null; -let gNextTest = null; let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); -Components.utils.import("resource://gre/modules/Services.jsm"); +let gTestBrowser = null; -// Let's do the XPCNativeWrapper dance! -function addPlugin(browser, type) { - let contentWindow = XPCNativeWrapper.unwrap(browser.contentWindow); - contentWindow.addPlugin(type); -} - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { +add_task(function* () { + registerCleanupFunction(Task.async(function*() { clearAllPluginPermissions(); Services.prefs.clearUserPref("plugins.click_to_play"); - }); - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); - - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", pageLoad, true); - prepareTest(testActivateAddSameTypePart1, gTestRoot + "plugin_add_dynamically.html"); -} - -function finishTest() { - gTestBrowser.removeEventListener("load", pageLoad, true); - gBrowser.removeCurrentTab(); - window.focus(); - finish(); -} - -function pageLoad() { - // The plugin events are async dispatched and can come after the load event - // This just allows the events to fire before we then go on to test the states - executeSoon(gNextTest); -} - -function prepareTest(nextTest, url) { - gNextTest = nextTest; - gTestBrowser.contentWindow.location = url; -} + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in"); + yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser); + resetBlocklist(); + gBrowser.removeCurrentTab(); + window.focus(); + gTestBrowser = null; + })); +}); // "Activate" of a given type -> plugins of that type dynamically added should // automatically play. -function testActivateAddSameTypePart1() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(!popupNotification, "testActivateAddSameTypePart1: should not have a click-to-play notification"); - addPlugin(gTestBrowser); - let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - waitForCondition(condition, testActivateAddSameTypePart2, "testActivateAddSameTypePart1: waited too long for click-to-play-plugin notification"); -} +add_task(function* () { + let newTab = gBrowser.addTab(); + gBrowser.selectedTab = newTab; + gTestBrowser = gBrowser.selectedBrowser; -function testActivateAddSameTypePart2() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "testActivateAddSameTypePart2: should have a click-to-play notification"); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + Services.prefs.setBoolPref("plugins.click_to_play", true); - popupNotification.reshow(); - testActivateAddSameTypePart3(); -} + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in"); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in"); +}); + +add_task(function* () { + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_add_dynamically.html"); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!notification, "Test 1a, Should not have a click-to-play notification"); + + // Add a plugin of type test + yield ContentTask.spawn(gTestBrowser, {}, function* () { + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("pluginone", "application/x-test")); + }); + + yield promisePopupNotification("click-to-play-plugins"); + + notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 1a, Should not have a click-to-play notification"); + + yield promiseForNotificationShown(notification); -function testActivateAddSameTypePart3() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); let centerAction = null; - for (let action of popupNotification.options.pluginData.values()) { + for (let action of notification.options.pluginData.values()) { if (action.pluginName == "Test") { centerAction = action; break; } } - ok(centerAction, "testActivateAddSameTypePart3: found center action for the Test plugin"); + ok(centerAction, "Test 2, found center action for the Test plugin"); let centerItem = null; for (let item of PopupNotifications.panel.firstChild.childNodes) { - if (item.action && item.action == centerAction) { + is(item.value, "block", "Test 3, all plugins should start out blocked"); + if (item.action == centerAction) { centerItem = item; break; } } - ok(centerItem, "testActivateAddSameTypePart3: found center item for the Test plugin"); + ok(centerItem, "Test 4, found center item for the Test plugin"); - let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0]; - ok(!plugin.activated, "testActivateAddSameTypePart3: plugin should not be activated"); - - // Change the state and click the ok button to activate the Test plugin + // Select the allow now option in the select drop down for Test Plugin centerItem.value = "allownow"; - PopupNotifications.panel.firstChild._primaryButton.click(); - - let condition = function() plugin.activated; - waitForCondition(condition, testActivateAddSameTypePart4, "testActivateAddSameTypePart3: waited too long for plugin to activate"); -} - -function testActivateAddSameTypePart4() { - let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0]; - ok(plugin.activated, "testActivateAddSameTypePart4: plugin should be activated"); - - addPlugin(gTestBrowser); - let condition = function() { - let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed"); - let allActivated = true; - for (let embed of embeds) { - if (!embed.activated) - allActivated = false; - } - return allActivated && embeds.length == 2; - }; - waitForCondition(condition, testActivateAddSameTypePart5, "testActivateAddSameTypePart4: waited too long for second plugin to activate"); } - -function testActivateAddSameTypePart5() { - let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed"); - for (let embed of embeds) { - ok(embed.activated, "testActivateAddSameTypePart5: all plugins should be activated"); - } - clearAllPluginPermissions(); - prepareTest(testActivateAddDifferentTypePart1, gTestRoot + "plugin_add_dynamically.html"); -} - -// "Activate" of a given type -> plugins of other types dynamically added -// should not automatically play. -function testActivateAddDifferentTypePart1() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(!popupNotification, "testActivateAddDifferentTypePart1: should not have a click-to-play notification"); - addPlugin(gTestBrowser); - let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - waitForCondition(condition, testActivateAddDifferentTypePart2, "testActivateAddDifferentTypePart1: waited too long for click-to-play-plugin notification"); -} - -function testActivateAddDifferentTypePart2() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - ok(popupNotification, "testActivateAddDifferentTypePart2: should have a click-to-play notification"); - - // we have to actually show the panel to get the bindings to instantiate - popupNotification.reshow(); - testActivateAddDifferentTypePart3(); -} - -function testActivateAddDifferentTypePart3() { - let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - is(popupNotification.options.pluginData.size, 1, "Should be one plugin action"); - - let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0]; - ok(!plugin.activated, "testActivateAddDifferentTypePart3: plugin should not be activated"); // "click" the button to activate the Test plugin PopupNotifications.panel.firstChild._primaryButton.click(); - let condition = function() plugin.activated; - waitForCondition(condition, testActivateAddDifferentTypePart4, "testActivateAddDifferentTypePart3: waited too long for plugin to activate"); -} + let pluginInfo = yield promiseForPluginInfo("pluginone"); + ok(pluginInfo.activated, "Test 5, plugin should be activated"); -function testActivateAddDifferentTypePart4() { - let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0]; - ok(plugin.activated, "testActivateAddDifferentTypePart4: plugin should be activated"); + // Add another plugin of type test + yield ContentTask.spawn(gTestBrowser, {}, function* () { + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("plugintwo", "application/x-test")); + }); - addPlugin(gTestBrowser); - let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); - waitForCondition(condition, testActivateAddDifferentTypePart5, "testActivateAddDifferentTypePart5: waited too long for popup notification"); -} + pluginInfo = yield promiseForPluginInfo("plugintwo"); + ok(pluginInfo.activated, "Test 6, plugins should be activated"); +}); -function testActivateAddDifferentTypePart5() { - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "testActivateAddDifferentTypePart5: should have popup notification"); - let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed"); - for (let embed of embeds) { - if (embed.type == "application/x-test") - ok(embed.activated, "testActivateAddDifferentTypePart5: Test plugin should be activated"); - else if (embed.type == "application/x-second-test") - ok(!embed.activated, "testActivateAddDifferentTypePart5: Second Test plugin should not be activated"); - } +// "Activate" of a given type -> plugins of other types dynamically added +// should not automatically play. +add_task(function* () { + clearAllPluginPermissions(); - finishTest(); -} + yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_add_dynamically.html"); + + let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!notification, "Test 7, Should not have a click-to-play notification"); + + // Add a plugin of type test + yield ContentTask.spawn(gTestBrowser, {}, function* () { + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("pluginone", "application/x-test")); + }); + + yield promisePopupNotification("click-to-play-plugins"); + + notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(notification, "Test 8, Should not have a click-to-play notification"); + + yield promiseForNotificationShown(notification); + + is(notification.options.pluginData.size, 1, "Should be one plugin action"); + + let pluginInfo = yield promiseForPluginInfo("pluginone"); + ok(!pluginInfo.activated, "Test 8, test plugin should be activated"); + + let condition = function() !notification.dismissed && + PopupNotifications.panel.firstChild; + yield promiseForCondition(condition); + + // "click" the button to activate the Test plugin + PopupNotifications.panel.firstChild._primaryButton.click(); + + pluginInfo = yield promiseForPluginInfo("pluginone"); + ok(pluginInfo.activated, "Test 9, test plugin should be activated"); + + yield ContentTask.spawn(gTestBrowser, {}, function* () { + new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("plugintwo", "application/x-second-test")); + }); + + yield promisePopupNotification("click-to-play-plugins"); + + pluginInfo = yield promiseForPluginInfo("pluginone"); + ok(pluginInfo.activated, "Test 10, plugins should be activated"); + pluginInfo = yield promiseForPluginInfo("plugintwo"); + ok(!pluginInfo.activated, "Test 11, plugins should be activated"); +}); diff --git a/browser/base/content/test/plugins/head.js b/browser/base/content/test/plugins/head.js index cbd6f569a4fb..f1fe67a80a2b 100644 --- a/browser/base/content/test/plugins/head.js +++ b/browser/base/content/test/plugins/head.js @@ -7,33 +7,122 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task", XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); -function whenDelayedStartupFinished(aWindow, aCallback) { - Services.obs.addObserver(function observer(aSubject, aTopic) { - if (aWindow == aSubject) { - Services.obs.removeObserver(observer, aTopic); - executeSoon(aCallback); +// The blocklist shim running in the content process does not initialize at +// start up, so it's not active until we load content that needs to do a +// check. This helper bypasses the delay to get the svc up and running +// immediately. Note, call this after remote content has loaded. +function promiseInitContentBlocklistSvc(aBrowser) +{ + return ContentTask.spawn(aBrowser, {}, function* () { + try { + let bls = Cc["@mozilla.org/extensions/blocklist;1"] + .getService(Ci.nsIBlocklistService); + } catch (ex) { + return ex.message; } - }, "browser-delayed-startup-finished", false); + return null; + }); } -function findChromeWindowByURI(aURI) { - let windows = Services.wm.getEnumerator(null); - while (windows.hasMoreElements()) { - let win = windows.getNext(); - if (win.location.href == aURI) - return win; +/** + * Waits a specified number of miliseconds. + * + * Usage: + * let wait = yield waitForMs(2000); + * ok(wait, "2 seconds should now have elapsed"); + * + * @param aMs the number of miliseconds to wait for + * @returns a Promise that resolves to true after the time has elapsed + */ +function waitForMs(aMs) { + let deferred = Promise.defer(); + let startTime = Date.now(); + setTimeout(done, aMs); + function done() { + deferred.resolve(true); } - return null; + return deferred.promise; } -function waitForCondition(condition, nextTest, errorMsg) { - var tries = 0; - var interval = setInterval(function() { - if (tries >= 30) { + +// DOM Promise fails for unknown reasons here, so we're using +// resource://gre/modules/Promise.jsm. +function waitForEvent(subject, eventName, checkFn, useCapture, useUntrusted) { + return new Promise((resolve, reject) => { + subject.addEventListener(eventName, function listener(event) { + try { + if (checkFn && !checkFn(event)) { + return; + } + subject.removeEventListener(eventName, listener, useCapture); + resolve(event); + } catch (ex) { + try { + subject.removeEventListener(eventName, listener, useCapture); + } catch (ex2) { + // Maybe the provided object does not support removeEventListener. + } + reject(ex); + } + }, useCapture, useUntrusted); + }); +} + + +/** + * Waits for a load (or custom) event to finish in a given tab. If provided + * load an uri into the tab. + * + * @param tab + * The tab to load into. + * @param [optional] url + * The url to load, or the current url. + * @param [optional] event + * The load event type to wait for. Defaults to "load". + * @return {Promise} resolved when the event is handled. + * @resolves to the received event + * @rejects if a valid load event is not received within a meaningful interval + */ +function promiseTabLoadEvent(tab, url, eventType="load") { + let deferred = Promise.defer(); + info("Wait tab event: " + eventType); + + function handle(event) { + if (event.originalTarget != tab.linkedBrowser.contentDocument || + event.target.location.href == "about:blank" || + (url && event.target.location.href != url)) { + info("Skipping spurious '" + eventType + "'' event" + + " for " + event.target.location.href); + return; + } + clearTimeout(timeout); + tab.linkedBrowser.removeEventListener(eventType, handle, true); + info("Tab event received: " + eventType); + deferred.resolve(event); + } + + let timeout = setTimeout(() => { + tab.linkedBrowser.removeEventListener(eventType, handle, true); + deferred.reject(new Error("Timed out while waiting for a '" + eventType + "'' event")); + }, 30000); + + tab.linkedBrowser.addEventListener(eventType, handle, true, true); + if (url) { + tab.linkedBrowser.loadURI(url); + } + return deferred.promise; +} + +function waitForCondition(condition, nextTest, errorMsg, aTries, aWait) { + let tries = 0; + let maxTries = aTries || 100; // 100 tries + let maxWait = aWait || 100; // 100 msec x 100 tries = ten seconds + let interval = setInterval(function() { + if (tries >= maxTries) { ok(false, errorMsg); moveOn(); } - var conditionPassed; + let conditionPassed; try { conditionPassed = condition(); } catch (e) { @@ -44,17 +133,27 @@ function waitForCondition(condition, nextTest, errorMsg) { moveOn(); } tries++; - }, 100); - var moveOn = function() { clearInterval(interval); nextTest(); }; + }, maxWait); + let moveOn = function() { clearInterval(interval); nextTest(); }; } +// Waits for a conditional function defined by the caller to return true. +function promiseForCondition(aConditionFn, aMessage, aTries, aWait) { + let deferred = Promise.defer(); + waitForCondition(aConditionFn, deferred.resolve, + (aMessage || "Condition didn't pass."), + aTries, aWait); + return deferred.promise; +} + +// Returns the chrome side nsIPluginTag for this plugin function getTestPlugin(aName) { - var pluginName = aName || "Test Plug-in"; - var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); - var tags = ph.getPluginTags(); + let pluginName = aName || "Test Plug-in"; + let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); + let tags = ph.getPluginTags(); // Find the test plugin - for (var i = 0; i < tags.length; i++) { + for (let i = 0; i < tags.length; i++) { if (tags[i].name == pluginName) return tags[i]; } @@ -62,15 +161,73 @@ function getTestPlugin(aName) { return null; } -// call this to set the test plugin(s) initially expected enabled state. -// it will automatically be reset to it's previous value after the test -// ends +// Set the 'enabledState' on the nsIPluginTag stored in the main or chrome +// process. function setTestPluginEnabledState(newEnabledState, pluginName) { - var plugin = getTestPlugin(pluginName); - var oldEnabledState = plugin.enabledState; + let name = pluginName || "Test Plug-in"; + let plugin = getTestPlugin(name); plugin.enabledState = newEnabledState; - SimpleTest.registerCleanupFunction(function() { - getTestPlugin(pluginName).enabledState = oldEnabledState; +} + +// Get the 'enabledState' on the nsIPluginTag stored in the main or chrome +// process. +function getTestPluginEnabledState(pluginName) { + let name = pluginName || "Test Plug-in"; + let plugin = getTestPlugin(name); + return plugin.enabledState; +} + +// Returns a promise for nsIObjectLoadingContent props data. +function promiseForPluginInfo(aId, aBrowser) { + let browser = aBrowser || gTestBrowser; + return ContentTask.spawn(browser, aId, function* (aId) { + let plugin = content.document.getElementById(aId); + if (!(plugin instanceof Ci.nsIObjectLoadingContent)) + throw new Error("no plugin found"); + return { + pluginFallbackType: plugin.pluginFallbackType, + activated: plugin.activated, + hasRunningPlugin: plugin.hasRunningPlugin, + displayedType: plugin.displayedType, + }; + }); +} + +// Return a promise and call the plugin's nsIObjectLoadingContent +// playPlugin() method. +function promisePlayObject(aId, aBrowser) { + let browser = aBrowser || gTestBrowser; + return ContentTask.spawn(browser, aId, function* (aId) { + let plugin = content.document.getElementById(aId); + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + objLoadingContent.playPlugin(); + }); +} + +function promiseCrashObject(aId, aBrowser) { + let browser = aBrowser || gTestBrowser; + return ContentTask.spawn(browser, aId, function* (aId) { + let plugin = content.document.getElementById(aId); + let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); + Components.utils.waiveXrays(plugin).crash(); + }); +} + +// Return a promise and call the plugin's getObjectValue() method. +function promiseObjectValueResult(aId, aBrowser) { + let browser = aBrowser || gTestBrowser; + return ContentTask.spawn(browser, aId, function* (aId) { + let plugin = content.document.getElementById(aId); + return Components.utils.waiveXrays(plugin).getObjectValue(); + }); +} + +// Return a promise and reload the target plugin in the page +function promiseReloadPlugin(aId, aBrowser) { + let browser = aBrowser || gTestBrowser; + return ContentTask.spawn(browser, aId, function* (aId) { + let plugin = content.document.getElementById(aId); + plugin.src = plugin.src; }); } @@ -81,15 +238,16 @@ function clearAllPluginPermissions() { while (perms.hasMoreElements()) { let perm = perms.getNext(); if (perm.type.startsWith('plugin')) { + info("removing permission:" + perm.host + " " + perm.type + "\n"); Services.perms.remove(perm.host, perm.type); } } } function updateBlocklist(aCallback) { - var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"] + let blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"] .getService(Ci.nsITimerCallback); - var observer = function() { + let observer = function() { Services.obs.removeObserver(observer, "blocklist-updated"); SimpleTest.executeSoon(aCallback); }; @@ -97,28 +255,77 @@ function updateBlocklist(aCallback) { blocklistNotifier.notify(null); } -var _originalTestBlocklistURL = null; +let _originalTestBlocklistURL = null; function setAndUpdateBlocklist(aURL, aCallback) { - if (!_originalTestBlocklistURL) + if (!_originalTestBlocklistURL) { _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url"); + } Services.prefs.setCharPref("extensions.blocklist.url", aURL); updateBlocklist(aCallback); } +// A generator that insures a new blocklist is loaded (in both +// processes if applicable). +function* asyncSetAndUpdateBlocklist(aURL, aBrowser) { + info("*** loading new blocklist: " + aURL); + let doTestRemote = aBrowser ? aBrowser.isRemoteBrowser : false; + if (!_originalTestBlocklistURL) { + _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url"); + } + Services.prefs.setCharPref("extensions.blocklist.url", aURL); + let localPromise = TestUtils.topicObserved("blocklist-updated"); + let remotePromise; + if (doTestRemote) { + remotePromise = TestUtils.topicObserved("content-blocklist-updated"); + } + let blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"] + .getService(Ci.nsITimerCallback); + blocklistNotifier.notify(null); + info("*** waiting on local load"); + yield localPromise; + if (doTestRemote) { + info("*** waiting on remote load"); + yield remotePromise; + } + info("*** blocklist loaded."); +} + +// Reset back to the blocklist we had at the start of the test run. function resetBlocklist() { Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL); } -function waitForNotificationPopup(notificationID, browser, callback) { - let notification; - waitForCondition( - () => (notification = PopupNotifications.getNotification(notificationID, browser)), - () => { - ok(notification, `Successfully got the ${notificationID} notification popup`); - callback(notification); - }, - `Waited too long for the ${notificationID} notification popup` - ); +// Insure there's a popup notification present. This test does not indicate +// open state. aBrowser can be undefined. +function promisePopupNotification(aName, aBrowser) { + let deferred = Promise.defer(); + + waitForCondition(() => PopupNotifications.getNotification(aName, aBrowser), + () => { + ok(!!PopupNotifications.getNotification(aName, aBrowser), + aName + " notification appeared"); + + deferred.resolve(); + }, "timeout waiting for popup notification " + aName); + + return deferred.promise; +} + +/** + * Allows setting focus on a window, and waiting for that window to achieve + * focus. + * + * @param aWindow + * The window to focus and wait for. + * + * @return {Promise} + * @resolves When the window is focused. + * @rejects Never. + */ +function promiseWaitForFocus(aWindow) { + return new Promise((resolve) => { + waitForFocus(resolve, aWindow); + }); } /** @@ -153,6 +360,12 @@ function waitForNotificationBar(notificationID, browser, callback) { }); } +function promiseForNotificationBar(notificationID, browser) { + let deferred = Promise.defer(); + waitForNotificationBar(notificationID, browser, deferred.resolve); + return deferred.promise; +} + /** * Reshow a notification and call a callback when it is reshown. * @param notification @@ -160,8 +373,7 @@ function waitForNotificationBar(notificationID, browser, callback) { * @param callback * A function to be called when the notification has been reshown */ -function waitForNotificationShown(notification, callback) -{ +function waitForNotificationShown(notification, callback) { if (PopupNotifications.panel.state == "open") { executeSoon(callback); return; @@ -173,46 +385,30 @@ function waitForNotificationShown(notification, callback) notification.reshow(); } -/** - * Due to layout being async, "PluginBindAttached" may trigger later. - * This returns a Promise that resolves once we've forced a layout - * flush, which triggers the PluginBindAttached event to fire. - * - * @param browser - * The browser to force plugin bindings in. - * - * @return Promise - */ -function forcePluginBindingAttached(browser) { - return new Promise((resolve, reject) => { - let doc = browser.contentDocument; - let elems = doc.getElementsByTagName('embed'); - if (elems.length < 1) { - elems = doc.getElementsByTagName('object'); - } - elems[0].clientTop; - executeSoon(resolve); - }); +function promiseForNotificationShown(notification) { + let deferred = Promise.defer(); + waitForNotificationShown(notification, deferred.resolve); + return deferred.promise; } /** - * Loads a page in a browser, and returns a Promise that - * resolves once the "load" event has been fired for that - * browser. - * + * Due to layout being async, "PluginBindAttached" may trigger later. This + * returns a Promise that resolves once we've forced a layout flush, which + * triggers the PluginBindAttached event to fire. This trick only works if + * there is some sort of plugin in the page. * @param browser - * The browser to load the page in. - * @param uri - * The URI to load. - * + * The browser to force plugin bindings in. * @return Promise */ -function loadPage(browser, uri) { - return new Promise((resolve, reject) => { - browser.addEventListener("load", function onLoad(event) { - browser.removeEventListener("load", onLoad, true); - resolve(); - }, true); - browser.loadURI(uri); +function promiseUpdatePluginBindings(browser) { + return ContentTask.spawn(browser, {}, function* () { + let doc = content.document; + let elems = doc.getElementsByTagName('embed'); + if (!elems || elems.length < 1) { + elems = doc.getElementsByTagName('object'); + } + if (elems && elems.length > 0) { + elems[0].clientTop; + } }); } diff --git a/browser/base/content/test/plugins/plugin_add_dynamically.html b/browser/base/content/test/plugins/plugin_add_dynamically.html index 3fdaf110ceed..863d36e0937b 100644 --- a/browser/base/content/test/plugins/plugin_add_dynamically.html +++ b/browser/base/content/test/plugins/plugin_add_dynamically.html @@ -1,15 +1,16 @@ - + diff --git a/browser/base/content/test/plugins/plugin_both.html b/browser/base/content/test/plugins/plugin_both.html index 2f3d2efe84cb..2335366dc0b7 100644 --- a/browser/base/content/test/plugins/plugin_both.html +++ b/browser/base/content/test/plugins/plugin_both.html @@ -1,7 +1,7 @@ - + - - + + diff --git a/browser/base/content/test/plugins/plugin_hidden_to_visible.html b/browser/base/content/test/plugins/plugin_hidden_to_visible.html index e8d92c68c41e..eeacc1874775 100644 --- a/browser/base/content/test/plugins/plugin_hidden_to_visible.html +++ b/browser/base/content/test/plugins/plugin_hidden_to_visible.html @@ -1,11 +1,11 @@ - + diff --git a/browser/base/content/test/plugins/plugin_syncRemoved.html b/browser/base/content/test/plugins/plugin_syncRemoved.html index e8d2070f7684..d977870561b2 100644 --- a/browser/base/content/test/plugins/plugin_syncRemoved.html +++ b/browser/base/content/test/plugins/plugin_syncRemoved.html @@ -1,4 +1,4 @@ - + @@ -6,6 +6,7 @@