summaryrefslogtreecommitdiff
path: root/browser/base/content/test/browser_pluginplaypreview.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/browser_pluginplaypreview.js')
-rw-r--r--browser/base/content/test/browser_pluginplaypreview.js317
1 files changed, 317 insertions, 0 deletions
diff --git a/browser/base/content/test/browser_pluginplaypreview.js b/browser/base/content/test/browser_pluginplaypreview.js
new file mode 100644
index 000000000..d1d8a53fb
--- /dev/null
+++ b/browser/base/content/test/browser_pluginplaypreview.js
@@ -0,0 +1,317 @@
+/* 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;
+
+var gTestBrowser = null;
+var gNextTest = null;
+var gNextTestSkip = 0;
+var gPlayPreviewPluginActualEvents = 0;
+var gPlayPreviewPluginExpectedEvents = 1;
+
+var gPlayPreviewRegistration = null;
+
+function registerPlayPreview(mimeType, targetUrl) {
+
+ function StreamConverterFactory() {}
+ StreamConverterFactory.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
+ _targetConstructor: null,
+
+ register: function register(targetConstructor) {
+ this._targetConstructor = targetConstructor;
+ var proto = targetConstructor.prototype;
+ var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.registerFactory(proto.classID, proto.classDescription,
+ proto.contractID, this);
+ },
+
+ unregister: function unregister() {
+ var proto = this._targetConstructor.prototype;
+ var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.unregisterFactory(proto.classID, this);
+ this._targetConstructor = null;
+ },
+
+ // nsIFactory
+ createInstance: function createInstance(aOuter, iid) {
+ if (aOuter !== null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return (new (this._targetConstructor)).QueryInterface(iid);
+ },
+
+ // nsIFactory
+ lockFactory: function lockFactory(lock) {
+ // No longer used as of gecko 1.7.
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ }
+ };
+
+ function OverlayStreamConverter() {}
+ OverlayStreamConverter.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsISupports,
+ Ci.nsIStreamConverter,
+ Ci.nsIStreamListener,
+ Ci.nsIRequestObserver
+ ]),
+
+ classID: Components.ID('{4c6030f7-e20a-264f-0f9b-ada3a9e97384}'),
+ classDescription: 'overlay-test-data Component',
+ contractID: '@mozilla.org/streamconv;1?from=application/x-moz-playpreview&to=*/*',
+
+ // nsIStreamConverter::convert
+ convert: function(aFromStream, aFromType, aToType, aCtxt) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ // nsIStreamConverter::asyncConvertData
+ asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
+ var isValidRequest = false;
+ try {
+ var request = aCtxt;
+ request.QueryInterface(Ci.nsIChannel);
+ var spec = request.URI.spec;
+ var expectedSpec = 'data:application/x-moz-playpreview;,' + mimeType;
+ isValidRequest = (spec == expectedSpec);
+ } catch (e) { }
+ if (!isValidRequest)
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+
+ // Store the listener passed to us
+ this.listener = aListener;
+ },
+
+ // nsIStreamListener::onDataAvailable
+ onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
+ // Do nothing since all the data loading is handled by the viewer.
+ ok(false, "onDataAvailable should not be called");
+ },
+
+ // nsIRequestObserver::onStartRequest
+ onStartRequest: function(aRequest, aContext) {
+
+ // Setup the request so we can use it below.
+ aRequest.QueryInterface(Ci.nsIChannel);
+ // Cancel the request so the viewer can handle it.
+ aRequest.cancel(Cr.NS_BINDING_ABORTED);
+
+ // Create a new channel that is viewer loaded as a resource.
+ var ioService = Services.io;
+ var channel = ioService.newChannel(targetUrl, null, null);
+ channel.asyncOpen(this.listener, aContext);
+ },
+
+ // nsIRequestObserver::onStopRequest
+ onStopRequest: function(aRequest, aContext, aStatusCode) {
+ // Do nothing.
+ }
+ };
+
+ var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+ ph.registerPlayPreviewMimeType(mimeType, true); // ignoring CTP rules
+
+ var factory = new StreamConverterFactory();
+ factory.register(OverlayStreamConverter);
+
+ return (gPlayPreviewRegistration = {
+ unregister: function() {
+ ph.unregisterPlayPreviewMimeType(mimeType);
+ factory.unregister();
+ gPlayPreviewRegistration = null;
+ }
+ });
+}
+
+function unregisterPlayPreview() {
+ gPlayPreviewRegistration.unregister();
+}
+
+Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+
+function test() {
+ waitForExplicitFinish();
+ registerCleanupFunction(function() {
+ if (gPlayPreviewRegistration)
+ gPlayPreviewRegistration.unregister();
+ Services.prefs.clearUserPref("plugins.click_to_play");
+ var plugin = getTestPlugin();
+ plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
+ });
+
+ var newTab = gBrowser.addTab();
+ gBrowser.selectedTab = newTab;
+ gTestBrowser = gBrowser.selectedBrowser;
+ gTestBrowser.addEventListener("load", pageLoad, true);
+ gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
+
+ registerPlayPreview('application/x-test', 'about:');
+ prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
+}
+
+function finishTest() {
+ gTestBrowser.removeEventListener("load", pageLoad, true);
+ gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
+ gBrowser.removeCurrentTab();
+ window.focus();
+ finish();
+}
+
+function handleBindingAttached(evt) {
+ if (evt.target instanceof Ci.nsIObjectLoadingContent &&
+ evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW)
+ gPlayPreviewPluginActualEvents++;
+}
+
+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
+
+ // iframe might triggers load event as well, making sure we skip some to let
+ // all iframes on the page be loaded as well
+ if (gNextTestSkip) {
+ gNextTestSkip--;
+ return;
+ }
+ executeSoon(gNextTest);
+}
+
+function prepareTest(nextTest, url, skip) {
+ gNextTest = nextTest;
+ gNextTestSkip = skip;
+ gTestBrowser.contentWindow.location = url;
+}
+
+// Tests a page with normal play preview registration (1/2)
+function test1a() {
+ var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+ ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 1a, Should not have displayed the missing plugin notification");
+ ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1a, Should not have displayed the blocked plugin notification");
+
+ var pluginInfo = getTestPlugin();
+ ok(pluginInfo, "Should have a test plugin");
+
+ var doc = gTestBrowser.contentDocument;
+ var plugin = doc.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
+ ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated");
+
+ var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
+ ok(overlay, "Test 1a, the overlay div is expected");
+
+ var iframe = overlay.getElementsByClassName("previewPluginContentFrame")[0];
+ ok(iframe && iframe.localName == "iframe", "Test 1a, the overlay iframe is expected");
+ var iframeHref = iframe.contentWindow.location.href;
+ ok(iframeHref == "about:", "Test 1a, the overlay about: content is expected");
+
+ var rect = iframe.getBoundingClientRect();
+ ok(rect.width == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being replaced by actual plugin");
+ ok(rect.height == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being replaced by actual plugin");
+
+ var e = overlay.ownerDocument.createEvent("CustomEvent");
+ e.initCustomEvent("MozPlayPlugin", true, true, null);
+ overlay.dispatchEvent(e);
+ var condition = function() objLoadingContent.activated;
+ waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin to stop play preview");
+}
+
+// Tests that activating via MozPlayPlugin through the notification works (part 2/2)
+function test1b() {
+ var plugin = gTestBrowser.contentDocument.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ ok(objLoadingContent.activated, "Test 1b, Plugin should be activated");
+
+ is(gPlayPreviewPluginActualEvents, gPlayPreviewPluginExpectedEvents,
+ "There should be exactly one PluginPlayPreview event");
+
+ unregisterPlayPreview();
+
+ prepareTest(test2, gTestRoot + "plugin_test.html");
+}
+
+// Tests a page with a working plugin in it -- the mime type was just unregistered.
+function test2() {
+ var plugin = gTestBrowser.contentDocument.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ ok(objLoadingContent.activated, "Test 2, Plugin should be activated");
+
+ registerPlayPreview('application/x-unknown', 'about:');
+
+ prepareTest(test3, gTestRoot + "plugin_test.html");
+}
+
+// Tests a page with a working plugin in it -- diffent play preview type is reserved.
+function test3() {
+ var plugin = gTestBrowser.contentDocument.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ ok(objLoadingContent.activated, "Test 3, Plugin should be activated");
+
+ unregisterPlayPreview();
+
+ registerPlayPreview('application/x-test', 'about:');
+ Services.prefs.setBoolPref("plugins.click_to_play", true);
+ var plugin = getTestPlugin();
+ plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+ prepareTest(test4a, gTestRoot + "plugin_test.html", 1);
+}
+
+// Test a fallback to the click-to-play
+function test4a() {
+ var doc = gTestBrowser.contentDocument;
+ var plugin = doc.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
+ ok(!objLoadingContent.activated, "Test 4a, Plugin should not be activated");
+
+ var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
+ ok(overlay, "Test 4a, the overlay div is expected");
+
+ var e = overlay.ownerDocument.createEvent("CustomEvent");
+ e.initCustomEvent("MozPlayPlugin", true, true, true);
+ overlay.dispatchEvent(e);
+ var condition = function() objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY;
+ waitForCondition(condition, test4b, "Test 4a, Waited too long for plugin to stop play preview");
+}
+
+function test4b() {
+ var doc = gTestBrowser.contentDocument;
+ var plugin = doc.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 4b, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
+ ok(!objLoadingContent.activated, "Test 4b, Plugin should not be activated");
+
+ prepareTest(test5a, gTestRoot + "plugin_test.html", 1);
+}
+
+// Test a bypass of the click-to-play
+function test5a() {
+ var doc = gTestBrowser.contentDocument;
+ var plugin = doc.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 5a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
+ ok(!objLoadingContent.activated, "Test 5a, Plugin should not be activated");
+
+ var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
+ ok(overlay, "Test 5a, the overlay div is expected");
+
+ var e = overlay.ownerDocument.createEvent("CustomEvent");
+ e.initCustomEvent("MozPlayPlugin", true, true, false);
+ overlay.dispatchEvent(e);
+ var condition = function() objLoadingContent.activated;
+ waitForCondition(condition, test5b, "Test 5a, Waited too long for plugin to stop play preview");
+}
+
+function test5b() {
+ var doc = gTestBrowser.contentDocument;
+ var plugin = doc.getElementById("test");
+ var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ ok(objLoadingContent.activated, "Test 5b, Plugin should be activated");
+
+ finishTest();
+}
+