2012-08-25 14:18:44 -07:00
/ * T h i s S o u r c e C o d e F o r m i s s u b j e c t t o t h e t e r m s o f t h e M o z i l l a P u b l i c
* 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 ) ;
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 newTab = gBrowser . addTab ( ) ;
gBrowser . selectedTab = newTab ;
gTestBrowser = gBrowser . selectedBrowser ;
gTestBrowser . addEventListener ( "load" , pageLoad , true ) ;
2012-11-07 13:59:20 -08:00
gTestBrowser . addEventListener ( "PluginBindingAttached" , handleBindingAttached , true , true ) ;
2012-08-25 14:18:44 -07:00
registerPlayPreview ( 'application/x-test' , 'about:' ) ;
prepareTest ( test1a , gTestRoot + "plugin_test.html" , 1 ) ;
}
function finishTest ( ) {
gTestBrowser . removeEventListener ( "load" , pageLoad , true ) ;
2012-11-07 13:59:20 -08:00
gTestBrowser . removeEventListener ( "PluginBindingAttached" , handleBindingAttached , true , true ) ;
2012-08-25 14:18:44 -07:00
gBrowser . removeCurrentTab ( ) ;
window . focus ( ) ;
finish ( ) ;
}
2012-11-07 13:59:20 -08:00
function handleBindingAttached ( evt ) {
if ( evt . target instanceof Ci . nsIObjectLoadingContent &&
evt . target . pluginFallbackType == Ci . nsIObjectLoadingContent . PLUGIN _PLAY _PREVIEW )
gPlayPreviewPluginActualEvents ++ ;
2012-08-25 14:18:44 -07:00
}
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 ) ;
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 ( ) ;
}