2014-06-25 05:12:07 +00:00
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- /
2006-09-05 21:50:54 +00:00
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
2012-05-21 11:12:37 +00: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/. */
2017-08-30 08:50:27 +00:00
"use strict" ;
2006-09-05 21:50:54 +00:00
2016-03-09 19:38:13 +00:00
this . EXPORTED _SYMBOLS = [ "OnRefTestLoad" , "OnRefTestUnload" ] ;
2011-12-20 21:33:41 +00:00
2015-10-07 12:03:21 +00:00
var CC = Components . classes ;
2006-09-05 21:50:54 +00:00
const CI = Components . interfaces ;
const CR = Components . results ;
2014-10-15 13:05:09 +00:00
const CU = Components . utils ;
2006-09-05 21:50:54 +00:00
const XHTML _NS = "http://www.w3.org/1999/xhtml" ;
2011-02-03 19:54:10 +00:00
const XUL _NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" ;
2006-09-05 21:50:54 +00:00
const NS _LOCAL _FILE _CONTRACTID = "@mozilla.org/file/local;1" ;
2010-08-13 15:44:21 +00:00
const NS _GFXINFO _CONTRACTID = "@mozilla.org/gfx/info;1" ;
2006-09-05 21:50:54 +00:00
const IO _SERVICE _CONTRACTID = "@mozilla.org/network/io-service;1" ;
2009-01-08 21:50:21 +00:00
const DEBUG _CONTRACTID = "@mozilla.org/xpcom/debug;1" ;
2006-09-05 21:50:54 +00:00
const NS _LOCALFILEINPUTSTREAM _CONTRACTID =
"@mozilla.org/network/file-input-stream;1" ;
2007-06-12 18:25:15 +00:00
const NS _SCRIPTSECURITYMANAGER _CONTRACTID =
"@mozilla.org/scriptsecuritymanager;1" ;
2007-08-03 02:28:55 +00:00
const NS _REFTESTHELPER _CONTRACTID =
"@mozilla.org/reftest-helper;1" ;
2008-08-06 22:38:44 +00:00
const NS _NETWORK _PROTOCOL _CONTRACTID _PREFIX =
"@mozilla.org/network/protocol;1?name=" ;
2009-02-03 14:11:28 +00:00
const NS _XREAPPINFO _CONTRACTID =
"@mozilla.org/xre/app-info;1" ;
2011-04-26 03:02:38 +00:00
const NS _DIRECTORY _SERVICE _CONTRACTID =
"@mozilla.org/file/directory_service;1" ;
const NS _OBSERVER _SERVICE _CONTRACTID =
"@mozilla.org/observer-service;1" ;
2009-02-03 14:11:28 +00:00
2014-10-24 21:58:25 +00:00
CU . import ( "resource://gre/modules/FileUtils.jsm" ) ;
CU . import ( "chrome://reftest/content/httpd.jsm" , this ) ;
2016-02-05 20:44:20 +00:00
CU . import ( "chrome://reftest/content/StructuredLog.jsm" , this ) ;
2014-10-24 21:58:25 +00:00
CU . import ( "resource://gre/modules/Services.jsm" ) ;
2015-12-15 21:33:44 +00:00
CU . import ( "resource://gre/modules/NetUtil.jsm" ) ;
2017-09-06 16:54:29 +00:00
CU . import ( 'resource://gre/modules/XPCOMUtils.jsm' ) ;
XPCOMUtils . defineLazyGetter ( this , "OS" , function ( ) {
const { OS } = CU . import ( "resource://gre/modules/osfile.jsm" ) ;
return OS ;
} ) ;
XPCOMUtils . defineLazyGetter ( this , "PDFJS" , function ( ) {
const { require } = CU . import ( "resource://gre/modules/commonjs/toolkit/require.js" , { } ) ;
return {
main : require ( 'resource://pdf.js/build/pdf.js' ) ,
worker : require ( 'resource://pdf.js/build/pdf.worker.js' )
} ;
} ) ;
2011-12-20 12:46:10 +00:00
2009-06-19 18:17:55 +00:00
var gLoadTimeout = 0 ;
2010-12-20 01:37:42 +00:00
var gTimeoutHook = null ;
2010-03-12 22:31:53 +00:00
var gRemote = false ;
2011-07-12 22:10:10 +00:00
var gIgnoreWindowSize = false ;
2014-03-03 05:13:01 +00:00
var gShuffle = false ;
2016-01-15 23:30:23 +00:00
var gRepeat = null ;
var gRunUntilFailure = false ;
2017-04-07 21:46:08 +00:00
var gCleanupPendingCrashes = false ;
2010-03-29 17:57:51 +00:00
var gTotalChunks = 0 ;
var gThisChunk = 0 ;
2011-12-15 12:41:40 +00:00
var gContainingWindow = null ;
2015-08-25 13:07:23 +00:00
var gURLFilterRegex = { } ;
2016-10-28 01:52:51 +00:00
var gContentGfxInfo = null ;
2013-06-07 13:46:26 +00:00
const FOCUS _FILTER _ALL _TESTS = "all" ;
const FOCUS _FILTER _NEEDS _FOCUS _TESTS = "needs-focus" ;
const FOCUS _FILTER _NON _NEEDS _FOCUS _TESTS = "non-needs-focus" ;
var gFocusFilterMode = FOCUS _FILTER _ALL _TESTS ;
2016-12-14 07:44:39 +00:00
var gCompareStyloToGecko = false ;
2007-02-12 02:21:18 +00:00
2009-02-10 22:05:27 +00:00
// "<!--CLEAR-->"
2013-01-20 01:23:45 +00:00
const BLANK _URL _FOR _CLEARING = "data:text/html;charset=UTF-8,%3C%21%2D%2DCLEAR%2D%2D%3E" ;
2009-02-10 22:05:27 +00:00
2006-09-05 21:50:54 +00:00
var gBrowser ;
2011-02-03 19:54:10 +00:00
// Are we testing web content loaded in a separate process?
var gBrowserIsRemote ; // bool
2012-08-17 15:45:39 +00:00
// Are we using <iframe mozbrowser>?
var gBrowserIsIframe ; // bool
2011-02-03 19:54:10 +00:00
var gBrowserMessageManager ;
2008-12-17 02:15:38 +00:00
var gCanvas1 , gCanvas2 ;
2009-01-06 01:15:13 +00:00
// gCurrentCanvas is non-null between InitCurrentCanvasWithSnapshot and the next
2010-12-20 01:37:42 +00:00
// RecordResult.
2009-01-06 01:15:13 +00:00
var gCurrentCanvas = null ;
2006-09-05 21:50:54 +00:00
var gURLs ;
2015-07-20 16:03:02 +00:00
var gManifestsLoaded = { } ;
2008-12-08 00:48:36 +00:00
// Map from URI spec to the number of times it remains to be used
var gURIUseCounts ;
// Map from URI spec to the canvas rendered for that URI
var gURICanvases ;
2008-12-02 12:35:24 +00:00
var gTestResults = {
2008-12-11 23:48:32 +00:00
// Successful...
Pass : 0 ,
LoadOnly : 0 ,
// Unexpected...
2008-12-02 12:35:24 +00:00
Exception : 0 ,
FailedLoad : 0 ,
UnexpectedFail : 0 ,
UnexpectedPass : 0 ,
2009-01-08 21:50:21 +00:00
AssertionUnexpected : 0 ,
AssertionUnexpectedFixed : 0 ,
2008-12-11 23:48:32 +00:00
// Known problems...
2008-12-02 12:35:24 +00:00
KnownFail : 0 ,
2009-01-08 21:50:21 +00:00
AssertionKnown : 0 ,
2008-12-02 12:35:24 +00:00
Random : 0 ,
Skip : 0 ,
2010-07-13 23:04:29 +00:00
Slow : 0 ,
2008-12-02 12:35:24 +00:00
} ;
2008-07-19 20:54:47 +00:00
var gTotalTests = 0 ;
2006-09-05 21:50:54 +00:00
var gState ;
2008-10-19 20:27:46 +00:00
var gCurrentURL ;
2010-12-20 01:37:43 +00:00
var gTestLog = [ ] ;
2016-02-05 20:44:20 +00:00
var gLogLevel ;
2007-07-18 21:32:50 +00:00
var gServer ;
var gCount = 0 ;
2009-01-08 21:50:21 +00:00
var gAssertionCount = 0 ;
2007-07-18 21:32:50 +00:00
var gIOService ;
2009-01-08 21:50:21 +00:00
var gDebug ;
2008-12-03 01:34:07 +00:00
var gWindowUtils ;
2006-09-05 21:50:54 +00:00
2008-04-30 00:39:45 +00:00
var gSlowestTestTime = 0 ;
var gSlowestTestURL ;
2016-07-11 01:11:08 +00:00
var gFailedUseWidgetLayers = false ;
2008-04-30 00:39:45 +00:00
2010-06-28 00:32:16 +00:00
var gDrawWindowFlags ;
2011-04-26 03:02:38 +00:00
var gExpectingProcessCrash = false ;
var gExpectedCrashDumpFiles = [ ] ;
var gUnexpectedCrashDumpFiles = { } ;
var gCrashDumpDir ;
2017-07-14 19:01:18 +00:00
var gPendingCrashDumpDir ;
2013-06-07 05:10:31 +00:00
var gFailedNoPaint = false ;
2015-03-11 18:51:59 +00:00
var gFailedOpaqueLayer = false ;
var gFailedOpaqueLayerMessages = [ ] ;
var gFailedAssignedLayer = false ;
var gFailedAssignedLayerMessages = [ ] ;
2011-04-26 03:02:38 +00:00
2017-03-09 02:49:20 +00:00
var gStartAfter = undefined ;
2017-09-23 15:07:03 +00:00
var gSuiteStarted = false
2017-03-09 02:49:20 +00:00
2013-09-04 14:05:31 +00:00
// The enabled-state of the test-plugins, stored so they can be reset later
var gTestPluginEnabledStates = null ;
2009-08-20 07:56:22 +00:00
const TYPE _REFTEST _EQUAL = '==' ;
const TYPE _REFTEST _NOTEQUAL = '!=' ;
const TYPE _LOAD = 'load' ; // test without a reference (just test that it does
// not assert, crash, hang, or leak)
const TYPE _SCRIPT = 'script' ; // test contains individual test results
2017-09-06 16:54:29 +00:00
const TYPE _PRINT = 'print' ; // test and reference will be printed to PDF's and
// compared structurally
2009-08-20 07:56:22 +00:00
2011-03-31 17:08:05 +00:00
// The order of these constants matters, since when we have a status
// listed for a *manifest*, we combine the status with the status for
2012-08-10 18:25:20 +00:00
// the test by using the *larger*.
2011-03-31 17:08:05 +00:00
// FIXME: In the future, we may also want to use this rule for combining
// statuses that are on the same line (rather than making the last one
// win).
2007-02-08 19:24:43 +00:00
const EXPECTED _PASS = 0 ;
const EXPECTED _FAIL = 1 ;
const EXPECTED _RANDOM = 2 ;
2007-05-08 10:21:22 +00:00
const EXPECTED _DEATH = 3 ; // test must be skipped to avoid e.g. crash/hang
2011-12-19 14:02:53 +00:00
const EXPECTED _FUZZY = 4 ;
2007-02-08 19:24:43 +00:00
2011-12-29 00:24:48 +00:00
// types of preference value we might want to set for a specific test
const PREF _BOOLEAN = 0 ;
const PREF _STRING = 1 ;
const PREF _INTEGER = 2 ;
var gPrefsToRestore = [ ] ;
2009-09-26 22:54:12 +00:00
const gProtocolRE = /^\w+:/ ;
2012-11-27 23:06:33 +00:00
const gPrefItemRE = /^(|test-|ref-)pref\((.+?),(.*)\)$/ ;
2009-09-26 22:54:12 +00:00
2013-06-17 18:59:52 +00:00
var gHttpServerPort = - 1 ;
2007-07-18 21:32:50 +00:00
2010-07-13 23:04:29 +00:00
// whether to run slow tests or not
var gRunSlowTests = true ;
2009-09-22 20:01:11 +00:00
// whether we should skip caching canvases
var gNoCanvasCache = false ;
2008-12-08 00:48:36 +00:00
var gRecycledCanvases = new Array ( ) ;
2011-02-03 19:54:10 +00:00
// Only dump the sandbox once, because it doesn't depend on the
// manifest URL (yet!).
var gDumpedConditionSandbox = false ;
2017-09-06 16:54:29 +00:00
var gTestPrintOutput = null ;
2016-01-15 23:30:23 +00:00
function HasUnexpectedResult ( )
{
return gTestResults . Exception > 0 ||
gTestResults . FailedLoad > 0 ||
gTestResults . UnexpectedFail > 0 ||
gTestResults . UnexpectedPass > 0 ||
gTestResults . AssertionUnexpected > 0 ||
gTestResults . AssertionUnexpectedFixed > 0 ;
}
2016-02-05 20:44:20 +00:00
// By default we just log to stdout
2016-03-09 19:38:13 +00:00
var gLogFile = null ;
2016-04-27 20:56:09 +00:00
var gDumpFn = function ( line ) {
dump ( line ) ;
if ( gLogFile ) {
gLogFile . write ( line , line . length ) ;
}
}
2016-02-05 20:44:20 +00:00
var gDumpRawLog = function ( record ) {
// Dump JSON representation of data on a single line
2016-03-09 19:38:13 +00:00
var line = "\n" + JSON . stringify ( record ) + "\n" ;
dump ( line ) ;
if ( gLogFile ) {
gLogFile . write ( line , line . length ) ;
}
2010-12-20 01:37:43 +00:00
}
2016-02-05 20:44:20 +00:00
var logger = new StructuredLogger ( 'reftest' , gDumpRawLog ) ;
2010-12-20 01:37:43 +00:00
2016-02-05 20:44:20 +00:00
function TestBuffer ( str )
2010-12-20 01:37:43 +00:00
{
2016-03-09 19:38:13 +00:00
logger . debug ( str ) ;
gTestLog . push ( str ) ;
2010-12-20 01:37:43 +00:00
}
2016-02-05 20:44:20 +00:00
function FlushTestBuffer ( )
2010-12-20 01:37:43 +00:00
{
2016-03-09 19:38:13 +00:00
// In debug mode, we've dumped all these messages already.
if ( gLogLevel !== 'debug' ) {
for ( var i = 0 ; i < gTestLog . length ; ++ i ) {
logger . info ( "Saved log: " + gTestLog [ i ] ) ;
2010-12-20 01:37:43 +00:00
}
2016-03-09 19:38:13 +00:00
}
gTestLog = [ ] ;
2010-12-20 01:37:43 +00:00
}
2016-07-11 01:11:08 +00:00
function LogWidgetLayersFailure ( )
{
logger . error ( "USE_WIDGET_LAYERS disabled because the screen resolution is too low. This falls back to an alternate rendering path (that may not be representative) and is not implemented with e10s enabled." ) ;
logger . error ( "Consider increasing your screen resolution, or adding '--disable-e10s' to your './mach reftest' command" ) ;
}
2008-12-08 00:48:36 +00:00
function AllocateCanvas ( )
{
2017-02-26 03:57:01 +00:00
if ( gRecycledCanvases . length > 0 ) {
2008-12-08 00:48:36 +00:00
return gRecycledCanvases . shift ( ) ;
2017-02-26 03:57:01 +00:00
}
2008-12-08 00:48:36 +00:00
2011-12-15 12:41:40 +00:00
var canvas = gContainingWindow . document . createElementNS ( XHTML _NS , "canvas" ) ;
2010-07-15 21:07:44 +00:00
var r = gBrowser . getBoundingClientRect ( ) ;
canvas . setAttribute ( "width" , Math . ceil ( r . width ) ) ;
canvas . setAttribute ( "height" , Math . ceil ( r . height ) ) ;
2009-09-22 20:01:11 +00:00
2008-12-08 00:48:36 +00:00
return canvas ;
}
function ReleaseCanvas ( canvas )
{
2009-09-22 20:01:11 +00:00
// store a maximum of 2 canvases, if we're not caching
2017-02-26 03:57:01 +00:00
if ( ! gNoCanvasCache || gRecycledCanvases . length < 2 ) {
2009-09-22 20:01:11 +00:00
gRecycledCanvases . push ( canvas ) ;
2017-02-26 03:57:01 +00:00
}
2008-12-08 00:48:36 +00:00
}
2010-12-20 01:37:43 +00:00
function IDForEventTarget ( event )
{
try {
return "'" + event . target . getAttribute ( 'id' ) + "'" ;
} catch ( ex ) {
return "<unknown>" ;
}
}
2013-09-04 14:05:31 +00:00
function getTestPlugin ( aName ) {
var ph = CC [ "@mozilla.org/plugin/host;1" ] . getService ( CI . nsIPluginHost ) ;
var tags = ph . getPluginTags ( ) ;
// Find the test plugin
for ( var i = 0 ; i < tags . length ; i ++ ) {
if ( tags [ i ] . name == aName )
return tags [ i ] ;
}
2016-02-05 20:44:20 +00:00
logger . warning ( "Failed to find the test-plugin." ) ;
2013-09-04 14:05:31 +00:00
return null ;
}
2012-10-31 16:13:28 +00:00
this . OnRefTestLoad = function OnRefTestLoad ( win )
2010-09-16 17:07:35 +00:00
{
2011-04-26 03:02:38 +00:00
gCrashDumpDir = CC [ NS _DIRECTORY _SERVICE _CONTRACTID ]
. getService ( CI . nsIProperties )
. get ( "ProfD" , CI . nsIFile ) ;
gCrashDumpDir . append ( "minidumps" ) ;
2012-08-10 18:25:20 +00:00
2017-04-07 21:46:08 +00:00
gPendingCrashDumpDir = CC [ NS _DIRECTORY _SERVICE _CONTRACTID ]
. getService ( CI . nsIProperties )
. get ( "UAppData" , CI . nsIFile ) ;
gPendingCrashDumpDir . append ( "Crash Reports" ) ;
gPendingCrashDumpDir . append ( "pending" ) ;
2011-06-10 17:00:11 +00:00
var env = CC [ "@mozilla.org/process/environment;1" ] .
getService ( CI . nsIEnvironment ) ;
2011-04-26 03:02:38 +00:00
2011-02-03 19:54:10 +00:00
var prefs = Components . classes [ "@mozilla.org/preferences-service;1" ] .
2012-01-17 02:01:25 +00:00
getService ( Components . interfaces . nsIPrefBranch ) ;
2017-03-07 14:29:48 +00:00
gBrowserIsRemote = prefs . getBoolPref ( "browser.tabs.remote.autostart" , false ) ;
2012-08-10 18:25:20 +00:00
2017-03-07 14:29:48 +00:00
gBrowserIsIframe = prefs . getBoolPref ( "reftest.browser.iframe.enabled" , false ) ;
2012-08-17 15:45:39 +00:00
2017-03-07 14:29:48 +00:00
gLogLevel = prefs . getCharPref ( "reftest.logLevel" , "info" ) ;
2016-02-05 20:44:20 +00:00
2011-12-20 21:33:41 +00:00
if ( win === undefined || win == null ) {
win = window ;
}
if ( gContainingWindow == null && win != null ) {
gContainingWindow = win ;
2011-12-15 12:41:40 +00:00
}
2011-02-03 19:54:10 +00:00
2012-08-17 15:45:39 +00:00
if ( gBrowserIsIframe ) {
gBrowser = gContainingWindow . document . createElementNS ( XHTML _NS , "iframe" ) ;
gBrowser . setAttribute ( "mozbrowser" , "" ) ;
} else {
gBrowser = gContainingWindow . document . createElementNS ( XUL _NS , "xul:browser" ) ;
2016-11-17 01:47:19 +00:00
gBrowser . setAttribute ( "class" , "lightweight" ) ;
2012-08-17 15:45:39 +00:00
}
2011-02-03 19:54:10 +00:00
gBrowser . setAttribute ( "id" , "browser" ) ;
2016-12-09 19:23:24 +00:00
gBrowser . setAttribute ( "type" , "content" ) ;
gBrowser . setAttribute ( "primary" , "true" ) ;
2011-02-03 19:54:10 +00:00
gBrowser . setAttribute ( "remote" , gBrowserIsRemote ? "true" : "false" ) ;
// Make sure the browser element is exactly 800x1000, no matter
// what size our window is
2014-06-19 01:39:00 +00:00
gBrowser . setAttribute ( "style" , "padding: 0px; margin: 0px; border:none; min-width: 800px; min-height: 1000px; max-width: 800px; max-height: 1000px" ) ;
2011-02-03 19:54:10 +00:00
2016-03-09 19:38:13 +00:00
if ( Services . appinfo . OS == "Android" ) {
2017-01-12 21:37:37 +00:00
let doc = gContainingWindow . document . getElementById ( 'main-window' ) ;
2016-03-09 19:38:13 +00:00
while ( doc . hasChildNodes ( ) ) {
2017-03-08 09:17:52 +00:00
doc . firstChild . remove ( ) ;
2016-03-09 19:38:13 +00:00
}
doc . appendChild ( gBrowser ) ;
} else {
document . getElementById ( "reftest-window" ) . appendChild ( gBrowser ) ;
2011-12-20 21:33:41 +00:00
}
2011-02-03 19:54:10 +00:00
2013-09-04 14:05:31 +00:00
// reftests should have the test plugins enabled, not click-to-play
let plugin1 = getTestPlugin ( "Test Plug-in" ) ;
let plugin2 = getTestPlugin ( "Second Test Plug-in" ) ;
if ( plugin1 && plugin2 ) {
gTestPluginEnabledStates = [ plugin1 . enabledState , plugin2 . enabledState ] ;
plugin1 . enabledState = CI . nsIPluginTag . STATE _ENABLED ;
plugin2 . enabledState = CI . nsIPluginTag . STATE _ENABLED ;
} else {
2016-02-05 20:44:20 +00:00
logger . warning ( "Could not get test plugin tags." ) ;
2013-09-04 14:05:31 +00:00
}
2017-08-19 20:32:58 +00:00
gBrowserMessageManager = gBrowser . frameLoader . messageManager ;
2011-02-03 19:54:10 +00:00
// The content script waits for the initial onload, then notifies
// us.
RegisterMessageListenersAndLoadContentScript ( ) ;
2010-09-16 17:07:35 +00:00
}
2011-02-03 19:54:10 +00:00
function InitAndStartRefTests ( )
2006-09-05 21:50:54 +00:00
{
2011-09-27 12:30:24 +00:00
/* These prefs are optional, so we don't need to spit an error to the log */
2009-06-19 18:17:55 +00:00
try {
2011-12-20 12:46:10 +00:00
var prefs = Components . classes [ "@mozilla.org/preferences-service;1" ] .
2012-01-17 02:01:25 +00:00
getService ( Components . interfaces . nsIPrefBranch ) ;
2011-09-27 12:30:24 +00:00
} catch ( e ) {
2016-02-05 20:44:20 +00:00
logger . error ( "EXCEPTION: " + e ) ;
2011-09-27 12:30:24 +00:00
}
2012-08-10 18:25:20 +00:00
2012-08-29 05:48:43 +00:00
try {
prefs . setBoolPref ( "android.widget_paints_background" , false ) ;
} catch ( e ) { }
2011-09-27 12:30:24 +00:00
/* set the gLoadTimeout */
try {
2011-12-20 12:46:10 +00:00
gLoadTimeout = prefs . getIntPref ( "reftest.timeout" ) ;
2012-08-10 18:25:20 +00:00
} catch ( e ) {
2011-12-20 12:46:10 +00:00
gLoadTimeout = 5 * 60 * 1000 ; //5 minutes as per bug 479518
2011-09-27 12:30:24 +00:00
}
2012-08-10 18:25:20 +00:00
2011-09-27 12:30:24 +00:00
/* Get the logfile for android tests */
try {
2012-04-10 17:56:59 +00:00
var logFile = prefs . getCharPref ( "reftest.logFile" ) ;
2011-12-20 12:46:10 +00:00
if ( logFile ) {
2016-03-09 19:38:13 +00:00
var f = FileUtils . File ( logFile ) ;
gLogFile = FileUtils . openFileOutputStream ( f , FileUtils . MODE _WRONLY | FileUtils . MODE _CREATE ) ;
2010-07-27 01:43:33 +00:00
}
2011-09-27 12:30:24 +00:00
} catch ( e ) { }
2012-08-10 18:25:20 +00:00
2017-03-07 14:29:48 +00:00
gRemote = prefs . getBoolPref ( "reftest.remote" , false ) ;
2012-07-04 00:21:03 +00:00
2017-03-07 14:29:48 +00:00
gIgnoreWindowSize = prefs . getBoolPref ( "reftest.ignoreWindowSize" , false ) ;
2010-03-29 17:57:51 +00:00
2010-04-09 04:03:47 +00:00
/* Support for running a chunk (subset) of tests. In separate try as this is optional */
2010-03-29 17:57:51 +00:00
try {
2011-12-20 12:46:10 +00:00
gTotalChunks = prefs . getIntPref ( "reftest.totalChunks" ) ;
gThisChunk = prefs . getIntPref ( "reftest.thisChunk" ) ;
2010-03-29 17:57:51 +00:00
}
catch ( e ) {
2011-12-20 12:46:10 +00:00
gTotalChunks = 0 ;
gThisChunk = 0 ;
2010-03-29 17:57:51 +00:00
}
2013-06-07 13:46:26 +00:00
try {
gFocusFilterMode = prefs . getCharPref ( "reftest.focusFilterMode" ) ;
} catch ( e ) { }
2017-03-09 02:49:20 +00:00
try {
gStartAfter = prefs . getCharPref ( "reftest.startAfter" ) ;
} catch ( e ) {
gStartAfter = undefined ;
}
2016-12-14 07:44:39 +00:00
# ifdef MOZ _STYLO
try {
gCompareStyloToGecko = prefs . getBoolPref ( "reftest.compareStyloToGecko" ) ;
} catch ( e ) { }
# endif
2017-09-06 16:54:29 +00:00
# ifdef MOZ _ENABLE _SKIA _PDF
try {
// We have to disable printing via parent or else silent print operations
// (the type that we use here) would be treated as non-silent -- in other
// words, a print dialog would appear for each print operation, which
// would interrupt the test run.
// See http://searchfox.org/mozilla-central/rev/bd39b6170f04afeefc751a23bb04e18bbd10352b/layout/printing/nsPrintEngine.cpp#617
prefs . setBoolPref ( "print.print_via_parent" , false ) ;
} catch ( e ) {
/* uh oh, print reftests may not work... */
}
# endif
2011-12-19 14:02:47 +00:00
gWindowUtils = gContainingWindow . QueryInterface ( CI . nsIInterfaceRequestor ) . getInterface ( CI . nsIDOMWindowUtils ) ;
if ( ! gWindowUtils || ! gWindowUtils . compareCanvases )
throw "nsIDOMWindowUtils inteface missing" ;
2007-08-03 02:28:55 +00:00
2007-07-18 21:32:50 +00:00
gIOService = CC [ IO _SERVICE _CONTRACTID ] . getService ( CI . nsIIOService ) ;
2009-01-08 21:50:21 +00:00
gDebug = CC [ DEBUG _CONTRACTID ] . getService ( CI . nsIDebug2 ) ;
2011-04-26 03:02:38 +00:00
RegisterProcessCrashObservers ( ) ;
2010-03-12 22:31:53 +00:00
if ( gRemote ) {
2011-12-20 12:46:10 +00:00
gServer = null ;
2010-03-12 22:31:53 +00:00
} else {
2014-12-16 06:07:01 +00:00
gServer = new HttpServer ( ) ;
2010-03-12 22:31:53 +00:00
}
2006-09-05 21:50:54 +00:00
try {
2009-04-15 20:19:35 +00:00
if ( gServer )
StartHTTPServer ( ) ;
} catch ( ex ) {
//gBrowser.loadURI('data:text/plain,' + ex);
++ gTestResults . Exception ;
2016-02-05 20:44:20 +00:00
logger . error ( "EXCEPTION: " + ex ) ;
2009-04-15 20:19:35 +00:00
DoneTests ( ) ;
}
2013-07-29 16:33:44 +00:00
// Focus the content browser.
if ( gFocusFilterMode != FOCUS _FILTER _NON _NEEDS _FOCUS _TESTS ) {
2017-01-23 20:57:19 +00:00
gBrowser . addEventListener ( "focus" , StartTests , true ) ;
2013-07-29 16:33:44 +00:00
gBrowser . focus ( ) ;
2017-01-23 20:57:19 +00:00
} else {
StartTests ( ) ;
2013-07-29 16:33:44 +00:00
}
2009-04-15 20:19:35 +00:00
}
function StartHTTPServer ( )
{
gServer . registerContentType ( "sjs" , "sjs" ) ;
2013-06-17 18:59:52 +00:00
gServer . start ( - 1 ) ;
gHttpServerPort = gServer . identity . primaryPort ;
2009-04-15 20:19:35 +00:00
}
2014-03-03 05:13:01 +00:00
// Perform a Fisher-Yates shuffle of the array.
function Shuffle ( array )
{
for ( var i = array . length - 1 ; i > 0 ; i -- ) {
var j = Math . floor ( Math . random ( ) * ( i + 1 ) ) ;
var temp = array [ i ] ;
array [ i ] = array [ j ] ;
array [ j ] = temp ;
}
}
2009-04-15 20:19:35 +00:00
function StartTests ( )
{
2017-01-23 20:57:19 +00:00
if ( gFocusFilterMode != FOCUS _FILTER _NON _NEEDS _FOCUS _TESTS ) {
gBrowser . removeEventListener ( "focus" , StartTests , true ) ;
}
2015-08-25 13:07:23 +00:00
var manifests ;
2011-12-20 21:33:41 +00:00
/* These prefs are optional, so we don't need to spit an error to the log */
try {
var prefs = Components . classes [ "@mozilla.org/preferences-service;1" ] .
2012-01-17 02:01:25 +00:00
getService ( Components . interfaces . nsIPrefBranch ) ;
2011-12-20 21:33:41 +00:00
} catch ( e ) {
2016-02-05 20:44:20 +00:00
logger . error ( "EXCEPTION: " + e ) ;
2011-12-20 21:33:41 +00:00
}
2012-08-10 18:25:20 +00:00
2017-03-07 14:29:48 +00:00
gNoCanvasCache = prefs . getIntPref ( "reftest.nocache" , false ) ;
2011-12-20 21:33:41 +00:00
2017-03-07 14:29:48 +00:00
gShuffle = prefs . getBoolPref ( "reftest.shuffle" , false ) ;
2014-03-03 05:13:01 +00:00
2017-03-07 14:29:48 +00:00
gRunUntilFailure = prefs . getBoolPref ( "reftest.runUntilFailure" , false ) ;
2016-01-15 23:30:23 +00:00
2017-04-07 21:46:08 +00:00
gCleanupPendingCrashes = prefs . getBoolPref ( "reftest.cleanupPendingCrashes" , false ) ;
2017-07-18 17:10:29 +00:00
// Check if there are any crash dump files from the startup procedure, before
// we start running the first test. Otherwise the first test might get
// blamed for producing a crash dump file when that was not the case.
CleanUpCrashDumpFiles ( ) ;
2016-01-15 23:30:23 +00:00
// When we repeat this function is called again, so really only want to set
// gRepeat once.
if ( gRepeat == null ) {
2017-03-07 14:29:48 +00:00
gRepeat = prefs . getIntPref ( "reftest.repeat" , 0 ) ;
2016-01-15 23:30:23 +00:00
}
2017-03-07 14:29:48 +00:00
gRunSlowTests = prefs . getIntPref ( "reftest.skipslowtests" , false ) ;
2011-12-20 21:33:41 +00:00
2015-08-25 13:07:23 +00:00
if ( gShuffle ) {
gNoCanvasCache = true ;
2011-12-20 21:33:41 +00:00
}
2015-08-25 13:07:23 +00:00
gURLs = [ ] ;
2016-01-15 23:30:23 +00:00
gManifestsLoaded = { } ;
2014-03-03 05:13:01 +00:00
2015-08-25 13:07:23 +00:00
try {
var manifests = JSON . parse ( prefs . getCharPref ( "reftest.manifests" ) ) ;
gURLFilterRegex = manifests [ null ] ;
} catch ( e ) {
2016-02-05 20:44:20 +00:00
logger . error ( "Unable to find reftest.manifests pref. Please ensure your profile is setup properly" ) ;
2015-08-25 13:07:23 +00:00
DoneTests ( ) ;
2014-03-03 05:13:01 +00:00
}
2011-12-20 21:33:41 +00:00
try {
2015-08-25 13:07:23 +00:00
var globalFilter = manifests . hasOwnProperty ( "" ) ? new RegExp ( manifests [ "" ] ) : null ;
var manifestURLs = Object . keys ( manifests ) ;
2015-07-20 16:03:02 +00:00
// Ensure we read manifests from higher up the directory tree first so that we
// process includes before reading the included manifest again
manifestURLs . sort ( function ( a , b ) { return a . length - b . length } )
2015-08-25 13:07:23 +00:00
manifestURLs . forEach ( function ( manifestURL ) {
2016-02-05 20:44:20 +00:00
logger . info ( "Reading manifest " + manifestURL ) ;
2015-07-20 16:03:02 +00:00
var filter = manifests [ manifestURL ] ? new RegExp ( manifests [ manifestURL ] ) : null ;
ReadTopManifest ( manifestURL , [ globalFilter , filter , false ] ) ;
2015-08-25 13:07:23 +00:00
} ) ;
2009-02-06 16:52:13 +00:00
BuildUseCounts ( ) ;
2010-03-29 17:57:51 +00:00
2013-01-03 21:33:23 +00:00
// Filter tests which will be skipped to get a more even distribution when chunking
// tURLs is a temporary array containing all active tests
var tURLs = new Array ( ) ;
2016-02-05 20:44:20 +00:00
var tIDs = new Array ( ) ;
2012-12-06 13:43:23 +00:00
for ( var i = 0 ; i < gURLs . length ; ++ i ) {
if ( gURLs [ i ] . expected == EXPECTED _DEATH )
continue ;
if ( gURLs [ i ] . needsFocus && ! Focus ( ) )
continue ;
if ( gURLs [ i ] . slow && ! gRunSlowTests )
continue ;
2013-01-03 21:33:23 +00:00
tURLs . push ( gURLs [ i ] ) ;
2016-02-05 20:44:20 +00:00
tIDs . push ( gURLs [ i ] . identifier ) ;
2012-12-06 13:43:23 +00:00
}
2017-09-23 15:07:03 +00:00
if ( gStartAfter === undefined && ! gSuiteStarted ) {
2017-06-14 16:10:10 +00:00
logger . suiteStart ( tIDs , { "skipped" : gURLs . length - tURLs . length } ) ;
2017-09-23 15:07:03 +00:00
gSuiteStarted = true
2017-06-14 16:10:10 +00:00
}
2012-12-06 13:43:23 +00:00
2010-03-29 17:57:51 +00:00
if ( gTotalChunks > 0 && gThisChunk > 0 ) {
2013-01-03 21:33:23 +00:00
// Calculate start and end indices of this chunk if tURLs array were
// divided evenly
var testsPerChunk = tURLs . length / gTotalChunks ;
2011-12-20 21:33:41 +00:00
var start = Math . round ( ( gThisChunk - 1 ) * testsPerChunk ) ;
var end = Math . round ( gThisChunk * testsPerChunk ) ;
2013-01-03 21:33:23 +00:00
// Map these indices onto the gURLs array. This avoids modifying the
// gURLs array which prevents skipped tests from showing up in the log
start = gThisChunk == 1 ? 0 : gURLs . indexOf ( tURLs [ start ] ) ;
end = gThisChunk == gTotalChunks ? gURLs . length : gURLs . indexOf ( tURLs [ end + 1 ] ) - 1 ;
2016-02-05 20:44:20 +00:00
logger . info ( "Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. " +
"tests " + ( start + 1 ) + "-" + end + "/" + gURLs . length ) ;
2017-08-30 16:11:28 +00:00
gURLs = gURLs . slice ( start , end ) ;
2010-03-29 17:57:51 +00:00
}
2014-03-03 05:13:01 +00:00
if ( gShuffle ) {
2017-03-09 02:49:20 +00:00
if ( gStartAfter !== undefined ) {
logger . error ( "Can't resume from a crashed test when " +
"--shuffle is enabled, continue by shuffling " +
"all the tests" ) ;
DoneTests ( ) ;
return ;
}
2014-03-03 05:13:01 +00:00
Shuffle ( gURLs ) ;
2017-03-09 02:49:20 +00:00
} else if ( gStartAfter !== undefined ) {
// Skip through previously crashed test
// We have to do this after chunking so we don't break the numbers
var crash _idx = gURLs . map ( function ( url ) {
return url [ 'url1' ] [ 'spec' ] ;
} ) . indexOf ( gStartAfter ) ;
if ( crash _idx == - 1 ) {
throw "Can't find the previously crashed test" ;
}
gURLs = gURLs . slice ( crash _idx + 1 ) ;
2014-03-03 05:13:01 +00:00
}
2008-07-19 20:54:47 +00:00
gTotalTests = gURLs . length ;
2009-05-14 14:17:45 +00:00
if ( ! gTotalTests )
throw "No tests to run" ;
2008-12-08 00:48:36 +00:00
gURICanvases = { } ;
2007-02-12 02:21:18 +00:00
StartCurrentTest ( ) ;
2006-09-05 21:50:54 +00:00
} catch ( ex ) {
2007-08-02 08:53:53 +00:00
//gBrowser.loadURI('data:text/plain,' + ex);
2008-12-02 12:35:24 +00:00
++ gTestResults . Exception ;
2016-02-05 20:44:20 +00:00
logger . error ( "EXCEPTION: " + ex ) ;
2007-08-02 08:53:53 +00:00
DoneTests ( ) ;
2006-09-05 21:50:54 +00:00
}
}
function OnRefTestUnload ( )
{
2013-09-04 14:05:31 +00:00
let plugin1 = getTestPlugin ( "Test Plug-in" ) ;
let plugin2 = getTestPlugin ( "Second Test Plug-in" ) ;
if ( plugin1 && plugin2 ) {
plugin1 . enabledState = gTestPluginEnabledStates [ 0 ] ;
plugin2 . enabledState = gTestPluginEnabledStates [ 1 ] ;
} else {
2016-02-05 20:44:20 +00:00
logger . warning ( "Failed to get test plugin tags." ) ;
2013-09-04 14:05:31 +00:00
}
2006-09-05 21:50:54 +00:00
}
2010-03-12 22:31:53 +00:00
// Read all available data from an input stream and return it
// as a string.
function getStreamContent ( inputStream )
{
2011-12-20 21:33:41 +00:00
var streamBuf = "" ;
var sis = CC [ "@mozilla.org/scriptableinputstream;1" ] .
createInstance ( CI . nsIScriptableInputStream ) ;
sis . init ( inputStream ) ;
var available ;
while ( ( available = sis . available ( ) ) != 0 ) {
streamBuf += sis . read ( available ) ;
}
return streamBuf ;
2010-03-12 22:31:53 +00:00
}
2010-06-09 01:44:32 +00:00
// Build the sandbox for fails-if(), etc., condition evaluation.
function BuildConditionSandbox ( aURL ) {
2010-03-30 20:58:30 +00:00
var sandbox = new Components . utils . Sandbox ( aURL . spec ) ;
2009-02-03 14:11:28 +00:00
var xr = CC [ NS _XREAPPINFO _CONTRACTID ] . getService ( CI . nsIXULRuntime ) ;
2014-01-23 21:02:22 +00:00
var appInfo = CC [ NS _XREAPPINFO _CONTRACTID ] . getService ( CI . nsIXULAppInfo ) ;
2009-08-20 07:56:22 +00:00
sandbox . isDebugBuild = gDebug . isDebugBuild ;
2017-05-15 08:53:02 +00:00
var prefs = CC [ "@mozilla.org/preferences-service;1" ] .
getService ( CI . nsIPrefBranch ) ;
2017-07-11 18:35:57 +00:00
var env = CC [ "@mozilla.org/process/environment;1" ] .
getService ( CI . nsIEnvironment ) ;
2009-06-19 18:17:55 +00:00
2009-10-22 20:36:24 +00:00
// xr.XPCOMABI throws exception for configurations without full ABI
// support (mobile builds on ARM)
2014-10-15 13:05:09 +00:00
var XPCOMABI = "" ;
2009-06-19 18:17:55 +00:00
try {
2014-10-15 13:05:09 +00:00
XPCOMABI = xr . XPCOMABI ;
} catch ( e ) { }
sandbox . xulRuntime = CU . cloneInto ( { widgetToolkit : xr . widgetToolkit , OS : xr . OS , XPCOMABI : XPCOMABI } , sandbox ) ;
2012-09-07 01:46:43 +00:00
2012-11-12 12:56:34 +00:00
var testRect = gBrowser . getBoundingClientRect ( ) ;
sandbox . smallScreen = false ;
if ( gContainingWindow . innerWidth < 800 || gContainingWindow . innerHeight < 1000 ) {
sandbox . smallScreen = true ;
}
2012-09-07 01:46:43 +00:00
2011-11-26 00:38:14 +00:00
var gfxInfo = ( NS _GFXINFO _CONTRACTID in CC ) && CC [ NS _GFXINFO _CONTRACTID ] . getService ( CI . nsIGfxInfo ) ;
2016-10-28 01:52:51 +00:00
let readGfxInfo = function ( obj , key ) {
if ( gContentGfxInfo && ( key in gContentGfxInfo ) ) {
return gContentGfxInfo [ key ] ;
}
return obj [ key ] ;
}
2010-08-13 15:44:21 +00:00
try {
2016-10-28 01:52:51 +00:00
sandbox . d2d = readGfxInfo ( gfxInfo , "D2DEnabled" ) ;
sandbox . dwrite = readGfxInfo ( gfxInfo , "DWriteEnabled" ) ;
2011-11-26 00:38:14 +00:00
} catch ( e ) {
sandbox . d2d = false ;
2016-08-18 23:06:51 +00:00
sandbox . dwrite = false ;
2010-08-13 15:44:21 +00:00
}
2016-10-28 01:52:51 +00:00
2012-07-31 06:30:10 +00:00
var info = gfxInfo . getInfo ( ) ;
2016-10-28 01:52:51 +00:00
var canvasBackend = readGfxInfo ( info , "AzureCanvasBackend" ) ;
var contentBackend = readGfxInfo ( info , "AzureContentBackend" ) ;
var canvasAccelerated = readGfxInfo ( info , "AzureCanvasAccelerated" ) ;
2016-11-14 23:02:02 +00:00
sandbox . gpuProcess = gfxInfo . usingGPUProcess ;
2016-10-28 01:52:51 +00:00
sandbox . azureCairo = canvasBackend == "cairo" ;
sandbox . azureSkia = canvasBackend == "skia" ;
sandbox . skiaContent = contentBackend == "skia" ;
sandbox . azureSkiaGL = canvasAccelerated ; // FIXME: assumes GL right now
2012-07-31 06:30:10 +00:00
// true if we are using the same Azure backend for rendering canvas and content
2016-10-28 01:52:51 +00:00
sandbox . contentSameGfxBackendAsCanvas = contentBackend == canvasBackend
|| ( contentBackend == "none" && canvasBackend == "cairo" ) ;
2010-09-03 18:02:23 +00:00
2011-03-31 21:33:46 +00:00
sandbox . layersGPUAccelerated =
2011-12-19 14:02:47 +00:00
gWindowUtils . layerManagerType != "Basic" ;
2015-10-01 02:45:26 +00:00
sandbox . d3d11 =
gWindowUtils . layerManagerType == "Direct3D 11" ;
2016-02-02 00:28:00 +00:00
sandbox . d3d9 =
gWindowUtils . layerManagerType == "Direct3D 9" ;
2011-03-31 21:33:46 +00:00
sandbox . layersOpenGL =
2011-12-19 14:02:47 +00:00
gWindowUtils . layerManagerType == "OpenGL" ;
2016-12-10 09:30:50 +00:00
sandbox . webrender =
gWindowUtils . layerManagerType == "WebRender" ;
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 09:20:52 +00:00
sandbox . layersOMTC =
gWindowUtils . layerManagerRemote == true ;
2017-06-23 21:23:13 +00:00
sandbox . advancedLayers =
gWindowUtils . usingAdvancedLayers == true ;
2017-09-27 14:12:10 +00:00
sandbox . layerChecksEnabled = ! sandbox . webrender ;
2011-03-31 21:33:46 +00:00
2010-06-09 01:44:32 +00:00
// Shortcuts for widget toolkits.
2017-01-12 21:37:37 +00:00
sandbox . Android = xr . OS == "Android" ;
2010-06-09 01:44:32 +00:00
sandbox . cocoaWidget = xr . widgetToolkit == "cocoa" ;
2015-06-02 17:47:00 +00:00
sandbox . gtkWidget = xr . widgetToolkit == "gtk2"
|| xr . widgetToolkit == "gtk3" ;
2010-06-09 01:44:32 +00:00
sandbox . qtWidget = xr . widgetToolkit == "qt" ;
sandbox . winWidget = xr . widgetToolkit == "windows" ;
2015-06-19 11:51:00 +00:00
// Scrollbars that are semi-transparent. See bug 1169666.
sandbox . transparentScrollbars = xr . widgetToolkit == "gtk3" ;
2013-06-24 12:51:32 +00:00
if ( sandbox . Android ) {
var sysInfo = CC [ "@mozilla.org/system-info;1" ] . getService ( CI . nsIPropertyBag2 ) ;
// This is currently used to distinguish Android 4.0.3 (SDK version 15)
// and later from Android 2.x
sandbox . AndroidVersion = sysInfo . getPropertyAsInt32 ( "version" ) ;
}
2013-01-21 23:46:40 +00:00
# if MOZ _ASAN
sandbox . AddressSanitizer = true ;
# else
sandbox . AddressSanitizer = false ;
# endif
2014-05-09 18:41:25 +00:00
# if MOZ _WEBRTC
sandbox . webrtc = true ;
# else
sandbox . webrtc = false ;
# endif
2016-12-14 06:58:27 +00:00
# ifdef MOZ _STYLO
2017-08-24 21:29:49 +00:00
let styloEnabled = false ;
// Perhaps a bit redundant in places, but this is easier to compare with the
// the real check in `nsLayoutUtils.cpp` to ensure they test the same way.
if ( env . get ( "STYLO_FORCE_ENABLED" ) ) {
styloEnabled = true ;
} else if ( env . get ( "STYLO_FORCE_DISABLED" ) ) {
styloEnabled = false ;
} else {
styloEnabled = prefs . getBoolPref ( "layout.css.servo.enabled" , false ) ;
}
sandbox . stylo = styloEnabled && ! gCompareStyloToGecko ;
2017-05-03 03:36:21 +00:00
sandbox . styloVsGecko = gCompareStyloToGecko ;
2016-12-14 06:58:27 +00:00
# else
2017-05-03 03:36:21 +00:00
sandbox . stylo = false ;
sandbox . styloVsGecko = false ;
2016-12-14 06:58:27 +00:00
# endif
2017-09-06 16:54:29 +00:00
// Printing via Skia PDF is only supported on Mac for now.
# ifdef XP _MACOSX && MOZ _ENABLE _SKIA _PDF
sandbox . skiaPdf = true ;
# else
sandbox . skiaPdf = false ;
# endif
2017-03-27 14:20:18 +00:00
# ifdef RELEASE _OR _BETA
sandbox . release _or _beta = true ;
# else
sandbox . release _or _beta = false ;
# endif
2008-08-06 22:38:44 +00:00
var hh = CC [ NS _NETWORK _PROTOCOL _CONTRACTID _PREFIX + "http" ] .
getService ( CI . nsIHttpProtocolHandler ) ;
2014-10-15 13:05:09 +00:00
var httpProps = [ "userAgent" , "appName" , "appVersion" , "vendor" ,
"vendorSub" , "product" , "productSub" , "platform" ,
"oscpu" , "language" , "misc" ] ;
sandbox . http = new sandbox . Object ( ) ;
httpProps . forEach ( ( x ) => sandbox . http [ x ] = hh [ x ] ) ;
2012-09-09 06:37:04 +00:00
2015-01-15 23:07:50 +00:00
// Set OSX to be the Mac OS X version, as an integer, or undefined
// for other platforms. The integer is formed by 100 times the
// major version plus the minor version, so 1006 for 10.6, 1010 for
// 10.10, etc.
var osxmatch = /Mac OS X (\d+).(\d+)$/ . exec ( hh . oscpu ) ;
sandbox . OSX = osxmatch ? parseInt ( osxmatch [ 1 ] ) * 100 + parseInt ( osxmatch [ 2 ] ) : undefined ;
2012-09-09 06:37:04 +00:00
2009-01-16 20:03:24 +00:00
// see if we have the test plugin available,
// and set a sandox prop accordingly
2017-09-22 17:32:40 +00:00
sandbox . haveTestPlugin = ! sandbox . Android && ! ! getTestPlugin ( "Test Plug-in" ) ;
2007-02-08 19:24:43 +00:00
2010-02-05 21:07:24 +00:00
// Set a flag on sandbox if the windows default theme is active
2014-08-08 10:46:48 +00:00
sandbox . windowsDefaultTheme = gContainingWindow . matchMedia ( "(-moz-windows-default-theme)" ) . matches ;
2010-02-05 21:07:24 +00:00
2010-03-02 22:14:14 +00:00
try {
sandbox . nativeThemePref = ! prefs . getBoolPref ( "mozilla.widget.disable-native-theme" ) ;
} catch ( e ) {
sandbox . nativeThemePref = true ;
}
2017-03-07 14:29:48 +00:00
sandbox . gpuProcessForceEnabled = prefs . getBoolPref ( "layers.gpu-process.force-enabled" , false ) ;
2010-03-02 22:14:14 +00:00
2014-10-15 13:05:09 +00:00
sandbox . prefs = CU . cloneInto ( {
getBoolPref : function ( p ) { return prefs . getBoolPref ( p ) ; } ,
getIntPref : function ( p ) { return prefs . getIntPref ( p ) ; }
} , sandbox , { cloneFunctions : true } ) ;
2010-03-29 21:56:46 +00:00
2011-02-03 19:54:10 +00:00
// Tests shouldn't care about this except for when they need to
// crash the content process
sandbox . browserIsRemote = gBrowserIsRemote ;
2014-07-26 19:21:57 +00:00
try {
2015-07-23 03:42:08 +00:00
sandbox . asyncPan = gContainingWindow . document . docShell . asyncPanZoomEnabled ;
2014-07-26 19:21:57 +00:00
} catch ( e ) {
2015-07-23 03:42:08 +00:00
sandbox . asyncPan = false ;
}
2014-07-26 19:21:57 +00:00
2017-08-01 21:16:17 +00:00
// Graphics features
sandbox . usesRepeatResampling = sandbox . d2d ;
2011-02-03 19:54:10 +00:00
if ( ! gDumpedConditionSandbox ) {
2016-02-05 20:44:20 +00:00
logger . info ( "Dumping JSON representation of sandbox" ) ;
logger . info ( JSON . stringify ( CU . waiveXrays ( sandbox ) ) ) ;
2011-02-03 19:54:10 +00:00
gDumpedConditionSandbox = true ;
}
2015-08-04 06:13:00 +00:00
2010-06-09 01:44:32 +00:00
return sandbox ;
}
2012-11-27 23:06:33 +00:00
function AddPrefSettings ( aWhere , aPrefName , aPrefValExpression , aSandbox , aTestPrefSettings , aRefPrefSettings )
{
var prefVal = Components . utils . evalInSandbox ( "(" + aPrefValExpression + ")" , aSandbox ) ;
var prefType ;
var valType = typeof ( prefVal ) ;
if ( valType == "boolean" ) {
prefType = PREF _BOOLEAN ;
} else if ( valType == "string" ) {
prefType = PREF _STRING ;
} else if ( valType == "number" && ( parseInt ( prefVal ) == prefVal ) ) {
prefType = PREF _INTEGER ;
} else {
return false ;
}
var setting = { name : aPrefName ,
type : prefType ,
value : prefVal } ;
2017-04-27 08:36:51 +00:00
if ( gCompareStyloToGecko && aPrefName != "layout.css.servo.enabled" ) {
// ref-pref() is ignored, test-pref() and pref() are added to both
if ( aWhere != "ref-" ) {
aTestPrefSettings . push ( setting ) ;
aRefPrefSettings . push ( setting ) ;
}
} else {
if ( aWhere != "ref-" ) {
aTestPrefSettings . push ( setting ) ;
}
if ( aWhere != "test-" ) {
aRefPrefSettings . push ( setting ) ;
}
2012-11-27 23:06:33 +00:00
}
return true ;
}
2015-07-20 16:03:02 +00:00
function ReadTopManifest ( aFileURL , aFilter )
2010-06-09 01:44:32 +00:00
{
2017-01-09 19:27:26 +00:00
var url = gIOService . newURI ( aFileURL ) ;
2010-06-09 01:44:32 +00:00
if ( ! url )
2011-12-20 21:33:41 +00:00
throw "Expected a file or http URL for the manifest." ;
2015-07-20 16:03:02 +00:00
ReadManifest ( url , EXPECTED _PASS , aFilter ) ;
2010-06-09 01:44:32 +00:00
}
2015-07-20 16:03:02 +00:00
function AddTestItem ( aTest , aFilter )
2012-11-27 22:29:03 +00:00
{
2015-07-20 16:03:02 +00:00
if ( ! aFilter )
aFilter = [ null , [ ] , false ] ;
2017-08-30 08:50:27 +00:00
var globalFilter = aFilter [ 0 ] ;
var manifestFilter = aFilter [ 1 ] ;
var invertManifest = aFilter [ 2 ] ;
2015-07-20 16:03:02 +00:00
if ( ( globalFilter && ! globalFilter . test ( aTest . url1 . spec ) ) ||
( manifestFilter &&
! ( invertManifest ^ manifestFilter . test ( aTest . url1 . spec ) ) ) )
2012-11-27 22:29:03 +00:00
return ;
2013-06-07 13:46:26 +00:00
if ( gFocusFilterMode == FOCUS _FILTER _NEEDS _FOCUS _TESTS &&
! aTest . needsFocus )
return ;
if ( gFocusFilterMode == FOCUS _FILTER _NON _NEEDS _FOCUS _TESTS &&
aTest . needsFocus )
return ;
2016-02-05 20:44:20 +00:00
if ( aTest . url2 !== null )
aTest . identifier = [ aTest . prettyPath , aTest . type , aTest . url2 . spec ] ;
else
aTest . identifier = aTest . prettyPath ;
2012-11-27 22:29:03 +00:00
gURLs . push ( aTest ) ;
}
2017-02-23 00:30:57 +00:00
function AddStyloTestPrefs ( aSandbox , aTestPrefSettings , aRefPrefSettings )
{
AddPrefSettings ( "test-" , "layout.css.servo.enabled" , "true" , aSandbox ,
aTestPrefSettings , aRefPrefSettings ) ;
AddPrefSettings ( "ref-" , "layout.css.servo.enabled" , "false" , aSandbox ,
aTestPrefSettings , aRefPrefSettings ) ;
}
2017-06-02 13:27:09 +00:00
function ExtractRange ( matches , startIndex , defaultMin = 0 ) {
if ( matches [ startIndex + 1 ] === undefined ) {
return {
min : defaultMin ,
max : Number ( matches [ startIndex ] )
} ;
}
return {
min : Number ( matches [ startIndex ] ) ,
max : Number ( matches [ startIndex + 1 ] . substring ( 1 ) )
} ;
}
2010-06-09 01:44:32 +00:00
// Note: If you materially change the reftest manifest parsing,
// please keep the parser in print-manifest-dirs.py in sync.
2015-07-20 16:03:02 +00:00
function ReadManifest ( aURL , inherited _status , aFilter )
2010-06-09 01:44:32 +00:00
{
2015-07-20 16:03:02 +00:00
// Ensure each manifest is only read once. This assumes that manifests that are
// included with an unusual inherited_status or filters will be read via their
// include before they are read directly in the case of a duplicate
if ( gManifestsLoaded . hasOwnProperty ( aURL . spec ) ) {
if ( gManifestsLoaded [ aURL . spec ] === null )
return ;
else
aFilter = [ aFilter [ 0 ] , aFilter [ 1 ] , true ] ;
}
gManifestsLoaded [ aURL . spec ] = aFilter [ 1 ] ;
2010-06-09 01:44:32 +00:00
var secMan = CC [ NS _SCRIPTSECURITYMANAGER _CONTRACTID ]
. getService ( CI . nsIScriptSecurityManager ) ;
var listURL = aURL ;
2015-12-15 21:33:44 +00:00
var channel = NetUtil . newChannel ( { uri : aURL , loadUsingSystemPrincipal : true } ) ;
var inputStream = channel . open2 ( ) ;
2010-06-09 01:44:32 +00:00
if ( channel instanceof Components . interfaces . nsIHttpChannel
&& channel . responseStatus != 200 ) {
2016-02-05 20:44:20 +00:00
logger . error ( "HTTP ERROR : " + channel . responseStatus ) ;
2010-06-09 01:44:32 +00:00
}
var streamBuf = getStreamContent ( inputStream ) ;
inputStream . close ( ) ;
2011-02-17 06:41:14 +00:00
var lines = streamBuf . split ( /\n|\r|\r\n/ ) ;
2010-06-09 01:44:32 +00:00
// Build the sandbox for fails-if(), etc., condition evaluation.
var sandbox = BuildConditionSandbox ( aURL ) ;
2006-09-05 21:50:54 +00:00
var lineNo = 0 ;
2009-09-26 22:54:12 +00:00
var urlprefix = "" ;
2012-11-27 23:06:33 +00:00
var defaultTestPrefSettings = [ ] , defaultRefPrefSettings = [ ] ;
2017-02-23 00:30:57 +00:00
if ( gCompareStyloToGecko ) {
AddStyloTestPrefs ( sandbox , defaultTestPrefSettings ,
defaultRefPrefSettings ) ;
}
2015-06-05 09:23:14 +00:00
for ( var str of lines ) {
2006-09-05 21:50:54 +00:00
++ lineNo ;
2007-12-20 23:49:00 +00:00
if ( str . charAt ( 0 ) == "#" )
2006-10-27 19:56:49 +00:00
continue ; // entire line was a comment
2007-12-20 23:49:00 +00:00
var i = str . search ( /\s+#/ ) ;
if ( i >= 0 )
str = str . substring ( 0 , i ) ;
2006-10-28 04:17:21 +00:00
// strip leading and trailing whitespace
str = str . replace ( /^\s*/ , '' ) . replace ( /\s*$/ , '' ) ;
2006-09-05 21:50:54 +00:00
if ( ! str || str == "" )
continue ;
var items = str . split ( /\s+/ ) ; // split on whitespace
2009-09-26 22:54:12 +00:00
if ( items [ 0 ] == "url-prefix" ) {
if ( items . length != 2 )
throw "url-prefix requires one url in manifest file " + aURL . spec + " line " + lineNo ;
urlprefix = items [ 1 ] ;
continue ;
}
2012-11-27 23:06:33 +00:00
if ( items [ 0 ] == "default-preferences" ) {
var m ;
var item ;
defaultTestPrefSettings = [ ] ;
defaultRefPrefSettings = [ ] ;
items . shift ( ) ;
while ( ( item = items . shift ( ) ) ) {
if ( ! ( m = item . match ( gPrefItemRE ) ) ) {
throw "Unexpected item in default-preferences list in manifest file " + aURL . spec + " line " + lineNo ;
}
if ( ! AddPrefSettings ( m [ 1 ] , m [ 2 ] , m [ 3 ] , sandbox , defaultTestPrefSettings , defaultRefPrefSettings ) ) {
throw "Error in pref value in manifest file " + aURL . spec + " line " + lineNo ;
}
}
2017-02-23 00:30:57 +00:00
if ( gCompareStyloToGecko ) {
AddStyloTestPrefs ( sandbox , defaultTestPrefSettings ,
defaultRefPrefSettings ) ;
}
2012-11-27 23:06:33 +00:00
continue ;
}
2007-02-08 19:24:43 +00:00
var expected _status = EXPECTED _PASS ;
2010-11-18 22:14:57 +00:00
var allow _silent _fail = false ;
2009-01-08 21:50:21 +00:00
var minAsserts = 0 ;
var maxAsserts = 0 ;
2011-02-03 19:54:10 +00:00
var needs _focus = false ;
2010-07-13 23:04:29 +00:00
var slow = false ;
2012-11-27 23:06:33 +00:00
var testPrefSettings = defaultTestPrefSettings . concat ( ) ;
var refPrefSettings = defaultRefPrefSettings . concat ( ) ;
2017-06-02 13:27:09 +00:00
var fuzzy _delta = { min : 0 , max : 2 } ;
var fuzzy _pixels = { min : 0 , max : 1 } ;
2015-06-04 17:44:55 +00:00
var chaosMode = false ;
2012-04-10 17:56:59 +00:00
2015-06-04 17:44:55 +00:00
while ( items [ 0 ] . match ( /^(fails|needs-focus|random|skip|asserts|slow|require-or|silentfail|pref|test-pref|ref-pref|fuzzy|chaos-mode)/ ) ) {
2007-02-08 19:24:43 +00:00
var item = items . shift ( ) ;
var stat ;
var cond ;
2012-01-23 07:56:12 +00:00
var m = item . match ( /^(fails|random|skip|silentfail)-if(\(.*\))$/ ) ;
2007-02-08 19:24:43 +00:00
if ( m ) {
stat = m [ 1 ] ;
// Note: m[2] contains the parentheses, and we want them.
cond = Components . utils . evalInSandbox ( m [ 2 ] , sandbox ) ;
2012-01-23 07:56:12 +00:00
} else if ( item . match ( /^(fails|random|skip)$/ ) ) {
2007-02-08 19:24:43 +00:00
stat = item ;
cond = true ;
2011-02-03 19:54:10 +00:00
} else if ( item == "needs-focus" ) {
needs _focus = true ;
2011-02-09 00:09:00 +00:00
cond = false ;
2009-01-08 21:50:21 +00:00
} else if ( ( m = item . match ( /^asserts\((\d+)(-\d+)?\)$/ ) ) ) {
cond = false ;
minAsserts = Number ( m [ 1 ] ) ;
maxAsserts = ( m [ 2 ] == undefined ) ? minAsserts
: Number ( m [ 2 ] . substring ( 1 ) ) ;
} else if ( ( m = item . match ( /^asserts-if\((.*?),(\d+)(-\d+)?\)$/ ) ) ) {
cond = false ;
if ( Components . utils . evalInSandbox ( "(" + m [ 1 ] + ")" , sandbox ) ) {
minAsserts = Number ( m [ 2 ] ) ;
maxAsserts =
( m [ 3 ] == undefined ) ? minAsserts
: Number ( m [ 3 ] . substring ( 1 ) ) ;
}
2010-07-13 23:04:29 +00:00
} else if ( item == "slow" ) {
cond = false ;
slow = true ;
2011-02-17 06:41:14 +00:00
} else if ( ( m = item . match ( /^require-or\((.*?)\)$/ ) ) ) {
var args = m [ 1 ] . split ( /,/ ) ;
if ( args . length != 2 ) {
2014-08-18 04:21:21 +00:00
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": wrong number of args to require-or" ;
2011-02-17 06:41:14 +00:00
}
var [ precondition _str , fallback _action ] = args ;
var preconditions = precondition _str . split ( /&&/ ) ;
cond = false ;
2015-06-05 09:23:14 +00:00
for ( var precondition of preconditions ) {
2011-02-17 06:41:14 +00:00
if ( precondition === "debugMode" ) {
// Currently unimplemented. Requires asynchronous
// JSD call + getting an event while no JS is running
stat = fallback _action ;
cond = true ;
break ;
} else if ( precondition === "true" ) {
// For testing
} else {
// Unknown precondition. Assume it is unimplemented.
stat = fallback _action ;
cond = true ;
break ;
}
}
2010-07-13 23:04:29 +00:00
} else if ( ( m = item . match ( /^slow-if\((.*?)\)$/ ) ) ) {
cond = false ;
if ( Components . utils . evalInSandbox ( "(" + m [ 1 ] + ")" , sandbox ) )
slow = true ;
2010-11-18 22:14:57 +00:00
} else if ( item == "silentfail" ) {
cond = false ;
allow _silent _fail = true ;
2012-11-27 23:06:33 +00:00
} else if ( ( m = item . match ( gPrefItemRE ) ) ) {
2011-12-29 00:24:48 +00:00
cond = false ;
2012-11-27 23:06:33 +00:00
if ( ! AddPrefSettings ( m [ 1 ] , m [ 2 ] , m [ 3 ] , sandbox , testPrefSettings , refPrefSettings ) ) {
2011-12-29 00:24:48 +00:00
throw "Error in pref value in manifest file " + aURL . spec + " line " + lineNo ;
}
2017-06-02 13:27:09 +00:00
} else if ( ( m = item . match ( /^fuzzy\((\d+)(-\d+)?,(\d+)(-\d+)?\)$/ ) ) ) {
2012-01-23 07:56:12 +00:00
cond = false ;
expected _status = EXPECTED _FUZZY ;
2017-06-02 13:27:09 +00:00
fuzzy _delta = ExtractRange ( m , 1 ) ;
fuzzy _pixels = ExtractRange ( m , 3 ) ;
} else if ( ( m = item . match ( /^fuzzy-if\((.*?),(\d+)(-\d+)?,(\d+)(-\d+)?\)$/ ) ) ) {
2012-01-23 07:56:12 +00:00
cond = false ;
if ( Components . utils . evalInSandbox ( "(" + m [ 1 ] + ")" , sandbox ) ) {
expected _status = EXPECTED _FUZZY ;
2017-06-02 13:27:09 +00:00
fuzzy _delta = ExtractRange ( m , 2 ) ;
fuzzy _pixels = ExtractRange ( m , 4 ) ;
2012-01-23 07:56:12 +00:00
}
2015-06-04 17:44:55 +00:00
} else if ( item == "chaos-mode" ) {
cond = false ;
chaosMode = true ;
2007-02-08 19:24:43 +00:00
} else {
2014-08-18 04:21:21 +00:00
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": unexpected item " + item ;
2007-02-08 19:24:43 +00:00
}
if ( cond ) {
if ( stat == "fails" ) {
expected _status = EXPECTED _FAIL ;
} else if ( stat == "random" ) {
expected _status = EXPECTED _RANDOM ;
2007-05-08 10:21:22 +00:00
} else if ( stat == "skip" ) {
expected _status = EXPECTED _DEATH ;
2010-11-18 22:14:57 +00:00
} else if ( stat == "silentfail" ) {
allow _silent _fail = true ;
2007-02-08 19:24:43 +00:00
}
}
}
2011-03-31 17:08:05 +00:00
expected _status = Math . max ( expected _status , inherited _status ) ;
2009-01-08 21:50:21 +00:00
if ( minAsserts > maxAsserts ) {
throw "Bad range in manifest file " + aURL . spec + " line " + lineNo ;
}
2008-11-08 16:35:54 +00:00
var runHttp = false ;
var httpDepth ;
if ( items [ 0 ] == "HTTP" ) {
2010-03-12 22:31:53 +00:00
runHttp = ( aURL . scheme == "file" ) ; // We can't yet run the local HTTP server
// for non-local reftests.
2008-11-08 16:35:54 +00:00
httpDepth = 0 ;
2007-07-18 21:32:50 +00:00
items . shift ( ) ;
2008-11-08 16:35:54 +00:00
} else if ( items [ 0 ] . match ( /HTTP\(\.\.(\/\.\.)*\)/ ) ) {
// Accept HTTP(..), HTTP(../..), HTTP(../../..), etc.
2010-03-12 22:31:53 +00:00
runHttp = ( aURL . scheme == "file" ) ; // We can't yet run the local HTTP server
// for non-local reftests.
2008-11-08 16:35:54 +00:00
httpDepth = ( items [ 0 ] . length - 5 ) / 3 ;
items . shift ( ) ;
}
2007-07-18 21:32:50 +00:00
2009-09-26 22:54:12 +00:00
// do not prefix the url for include commands or urls specifying
// a protocol
if ( urlprefix && items [ 0 ] != "include" ) {
if ( items . length > 1 && ! items [ 1 ] . match ( gProtocolRE ) ) {
items [ 1 ] = urlprefix + items [ 1 ] ;
}
if ( items . length > 2 && ! items [ 2 ] . match ( gProtocolRE ) ) {
items [ 2 ] = urlprefix + items [ 2 ] ;
}
}
2016-05-24 10:01:34 +00:00
var principal = secMan . createCodebasePrincipal ( aURL , { } ) ;
2012-07-18 22:27:02 +00:00
2006-09-05 21:50:54 +00:00
if ( items [ 0 ] == "include" ) {
2014-08-18 04:21:21 +00:00
if ( items . length != 2 )
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect number of arguments to include" ;
if ( runHttp )
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": use of include with http" ;
2007-07-18 21:32:50 +00:00
var incURI = gIOService . newURI ( items [ 1 ] , null , listURL ) ;
2012-07-18 22:27:02 +00:00
secMan . checkLoadURIWithPrincipal ( principal , incURI ,
CI . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
2015-07-20 16:03:02 +00:00
ReadManifest ( incURI , expected _status , aFilter ) ;
2009-08-20 07:56:22 +00:00
} else if ( items [ 0 ] == TYPE _LOAD ) {
2014-08-18 04:21:21 +00:00
if ( items . length != 2 )
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect number of arguments to load" ;
if ( expected _status != EXPECTED _PASS &&
expected _status != EXPECTED _DEATH )
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect known failure type for load test" ;
2007-10-03 21:27:04 +00:00
var [ testURI ] = runHttp
2012-07-18 22:27:02 +00:00
? ServeFiles ( principal , httpDepth ,
2010-03-12 22:31:53 +00:00
listURL , [ items [ 1 ] ] )
2007-10-03 21:27:04 +00:00
: [ gIOService . newURI ( items [ 1 ] , null , listURL ) ] ;
var prettyPath = runHttp
? gIOService . newURI ( items [ 1 ] , null , listURL ) . spec
: testURI . spec ;
2012-07-18 22:27:02 +00:00
secMan . checkLoadURIWithPrincipal ( principal , testURI ,
CI . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
2012-11-27 22:29:03 +00:00
AddTestItem ( { type : TYPE _LOAD ,
2007-10-03 21:27:04 +00:00
expected : expected _status ,
2010-11-18 22:14:57 +00:00
allowSilentFail : allow _silent _fail ,
2007-10-03 21:27:04 +00:00
prettyPath : prettyPath ,
2009-01-08 21:50:21 +00:00
minAsserts : minAsserts ,
maxAsserts : maxAsserts ,
2011-02-03 19:54:10 +00:00
needsFocus : needs _focus ,
2010-07-13 23:04:29 +00:00
slow : slow ,
2012-04-10 17:56:59 +00:00
prefSettings1 : testPrefSettings ,
prefSettings2 : refPrefSettings ,
2017-06-02 13:27:09 +00:00
fuzzyMinDelta : fuzzy _delta . min ,
fuzzyMaxDelta : fuzzy _delta . max ,
fuzzyMinPixels : fuzzy _pixels . min ,
fuzzyMaxPixels : fuzzy _pixels . max ,
2008-12-17 02:15:38 +00:00
url1 : testURI ,
2015-06-04 17:44:55 +00:00
url2 : null ,
2015-07-20 16:03:02 +00:00
chaosMode : chaosMode } , aFilter ) ;
2009-08-20 07:56:22 +00:00
} else if ( items [ 0 ] == TYPE _SCRIPT ) {
if ( items . length != 2 )
2014-08-18 04:21:21 +00:00
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect number of arguments to script" ;
2009-08-20 07:56:22 +00:00
var [ testURI ] = runHttp
2012-07-18 22:27:02 +00:00
? ServeFiles ( principal , httpDepth ,
2010-03-12 22:31:53 +00:00
listURL , [ items [ 1 ] ] )
2009-08-20 07:56:22 +00:00
: [ gIOService . newURI ( items [ 1 ] , null , listURL ) ] ;
var prettyPath = runHttp
? gIOService . newURI ( items [ 1 ] , null , listURL ) . spec
: testURI . spec ;
2012-07-18 22:27:02 +00:00
secMan . checkLoadURIWithPrincipal ( principal , testURI ,
CI . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
2012-11-27 22:29:03 +00:00
AddTestItem ( { type : TYPE _SCRIPT ,
2009-08-20 07:56:22 +00:00
expected : expected _status ,
2010-11-18 22:14:57 +00:00
allowSilentFail : allow _silent _fail ,
2009-08-20 07:56:22 +00:00
prettyPath : prettyPath ,
minAsserts : minAsserts ,
maxAsserts : maxAsserts ,
2011-02-03 19:54:10 +00:00
needsFocus : needs _focus ,
2010-07-13 23:04:29 +00:00
slow : slow ,
2012-04-10 17:56:59 +00:00
prefSettings1 : testPrefSettings ,
prefSettings2 : refPrefSettings ,
2017-06-02 13:27:09 +00:00
fuzzyMinDelta : fuzzy _delta . min ,
fuzzyMaxDelta : fuzzy _delta . max ,
fuzzyMinPixels : fuzzy _pixels . min ,
fuzzyMaxPixels : fuzzy _pixels . max ,
2009-08-20 07:56:22 +00:00
url1 : testURI ,
2015-06-04 17:44:55 +00:00
url2 : null ,
2015-07-20 16:03:02 +00:00
chaosMode : chaosMode } , aFilter ) ;
2017-09-06 16:54:29 +00:00
} else if ( items [ 0 ] == TYPE _REFTEST _EQUAL || items [ 0 ] == TYPE _REFTEST _NOTEQUAL || items [ 0 ] == TYPE _PRINT ) {
2009-08-20 07:56:22 +00:00
if ( items . length != 3 )
2014-08-18 04:21:21 +00:00
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect number of arguments to " + items [ 0 ] ;
2017-06-02 13:27:09 +00:00
if ( items [ 0 ] == TYPE _REFTEST _NOTEQUAL &&
expected _status == EXPECTED _FUZZY &&
( fuzzy _delta . min > 0 || fuzzy _pixels . min > 0 ) ) {
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": minimum fuzz must be zero for tests of type " + items [ 0 ] ;
}
2007-07-18 21:32:50 +00:00
var [ testURI , refURI ] = runHttp
2012-07-18 22:27:02 +00:00
? ServeFiles ( principal , httpDepth ,
2010-03-12 22:31:53 +00:00
listURL , [ items [ 1 ] , items [ 2 ] ] )
2007-07-18 21:32:50 +00:00
: [ gIOService . newURI ( items [ 1 ] , null , listURL ) ,
gIOService . newURI ( items [ 2 ] , null , listURL ) ] ;
var prettyPath = runHttp
? gIOService . newURI ( items [ 1 ] , null , listURL ) . spec
: testURI . spec ;
2012-07-18 22:27:02 +00:00
secMan . checkLoadURIWithPrincipal ( principal , testURI ,
CI . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
secMan . checkLoadURIWithPrincipal ( principal , refURI ,
CI . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
2017-04-27 08:36:51 +00:00
var type = items [ 0 ] ;
if ( gCompareStyloToGecko ) {
type = TYPE _REFTEST _EQUAL ;
refURI = testURI ;
2017-09-02 03:39:44 +00:00
2017-09-04 03:22:35 +00:00
// We expect twice as many assertion failures when running in
// styloVsGecko mode because we run each test twice: once in
// Stylo mode and once in Gecko mode.
minAsserts *= 2 ;
maxAsserts *= 2 ;
2017-09-02 03:39:44 +00:00
// Skip the test if it is expected to fail in both Stylo and
// Gecko modes. It would unexpectedly "pass" in styloVsGecko
// mode when comparing the two failures, which is not a useful
// result.
if ( expected _status === EXPECTED _FAIL ||
expected _status === EXPECTED _RANDOM ) {
expected _status = EXPECTED _DEATH ;
}
2017-04-27 08:36:51 +00:00
}
2017-09-02 03:39:44 +00:00
2017-04-27 08:36:51 +00:00
AddTestItem ( { type : type ,
2007-02-08 19:24:43 +00:00
expected : expected _status ,
2010-11-18 22:14:57 +00:00
allowSilentFail : allow _silent _fail ,
2007-07-18 21:32:50 +00:00
prettyPath : prettyPath ,
2009-01-08 21:50:21 +00:00
minAsserts : minAsserts ,
maxAsserts : maxAsserts ,
2011-02-03 19:54:10 +00:00
needsFocus : needs _focus ,
2010-07-13 23:04:29 +00:00
slow : slow ,
2012-04-10 17:56:59 +00:00
prefSettings1 : testPrefSettings ,
prefSettings2 : refPrefSettings ,
2017-06-02 13:27:09 +00:00
fuzzyMinDelta : fuzzy _delta . min ,
fuzzyMaxDelta : fuzzy _delta . max ,
fuzzyMinPixels : fuzzy _pixels . min ,
fuzzyMaxPixels : fuzzy _pixels . max ,
2008-12-17 02:15:38 +00:00
url1 : testURI ,
2015-06-04 17:44:55 +00:00
url2 : refURI ,
2015-07-20 16:03:02 +00:00
chaosMode : chaosMode } , aFilter ) ;
2006-09-05 21:50:54 +00:00
} else {
2014-08-18 04:21:21 +00:00
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": unknown test type " + items [ 0 ] ;
2006-09-05 21:50:54 +00:00
}
2010-03-12 22:31:53 +00:00
}
2006-09-05 21:50:54 +00:00
}
2008-12-17 02:15:38 +00:00
function AddURIUseCount ( uri )
2008-12-08 00:48:36 +00:00
{
if ( uri == null )
return ;
2008-12-17 02:15:38 +00:00
var spec = uri . spec ;
2008-12-08 00:48:36 +00:00
if ( spec in gURIUseCounts ) {
gURIUseCounts [ spec ] ++ ;
} else {
gURIUseCounts [ spec ] = 1 ;
}
}
function BuildUseCounts ( )
{
2017-02-26 03:57:01 +00:00
if ( gNoCanvasCache ) {
return ;
}
2008-12-08 00:48:36 +00:00
gURIUseCounts = { } ;
for ( var i = 0 ; i < gURLs . length ; ++ i ) {
2009-08-20 07:56:22 +00:00
var url = gURLs [ i ] ;
if ( url . expected != EXPECTED _DEATH &&
( url . type == TYPE _REFTEST _EQUAL ||
2012-04-10 17:56:59 +00:00
url . type == TYPE _REFTEST _NOTEQUAL ) ) {
if ( url . prefSettings1 . length == 0 ) {
AddURIUseCount ( gURLs [ i ] . url1 ) ;
}
if ( url . prefSettings2 . length == 0 ) {
AddURIUseCount ( gURLs [ i ] . url2 ) ;
}
2008-12-08 00:48:36 +00:00
}
}
}
2012-07-18 22:27:02 +00:00
function ServeFiles ( manifestPrincipal , depth , aURL , files )
2007-07-18 21:32:50 +00:00
{
2010-03-12 22:31:53 +00:00
var listURL = aURL . QueryInterface ( CI . nsIFileURL ) ;
var directory = listURL . file . parent ;
2008-11-08 16:35:54 +00:00
// Allow serving a tree that's an ancestor of the directory containing
// the files so that they can use resources in ../ (etc.).
var dirPath = "/" ;
while ( depth > 0 ) {
dirPath = "/" + directory . leafName + dirPath ;
directory = directory . parent ;
-- depth ;
}
2007-07-18 21:32:50 +00:00
gCount ++ ;
2011-04-13 13:35:06 +00:00
var path = "/" + Date . now ( ) + "/" + gCount ;
2008-11-08 16:35:54 +00:00
gServer . registerDirectory ( path + "/" , directory ) ;
2007-07-18 21:32:50 +00:00
var secMan = CC [ NS _SCRIPTSECURITYMANAGER _CONTRACTID ]
. getService ( CI . nsIScriptSecurityManager ) ;
2013-06-17 18:59:52 +00:00
var testbase = gIOService . newURI ( "http://localhost:" + gHttpServerPort +
2017-01-09 19:27:26 +00:00
path + dirPath ) ;
2008-11-08 16:35:54 +00:00
2015-06-16 19:30:13 +00:00
// Give the testbase URI access to XUL and XBL
Services . perms . add ( testbase , "allowXULXBL" , Services . perms . ALLOW _ACTION ) ;
2007-10-03 21:27:04 +00:00
function FileToURI ( file )
{
2008-11-08 16:35:54 +00:00
// Only serve relative URIs via the HTTP server, not absolute
// ones like about:blank.
var testURI = gIOService . newURI ( file , null , testbase ) ;
2007-10-03 21:27:04 +00:00
// XXX necessary? manifestURL guaranteed to be file, others always HTTP
2012-07-18 22:27:02 +00:00
secMan . checkLoadURIWithPrincipal ( manifestPrincipal , testURI ,
CI . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
2007-07-18 21:32:50 +00:00
2007-10-03 21:27:04 +00:00
return testURI ;
}
return files . map ( FileToURI ) ;
2007-07-18 21:32:50 +00:00
}
2011-02-03 19:54:10 +00:00
// Return true iff this window is focused when this function returns.
function Focus ( )
{
2011-10-01 19:50:19 +00:00
var fm = CC [ "@mozilla.org/focus-manager;1" ] . getService ( CI . nsIFocusManager ) ;
2012-01-12 19:49:52 +00:00
fm . focusedWindow = gContainingWindow ;
2013-02-23 06:32:30 +00:00
# ifdef XP _MACOSX
2011-10-01 19:50:19 +00:00
try {
var dock = CC [ "@mozilla.org/widget/macdocksupport;1" ] . getService ( CI . nsIMacDockSupport ) ;
dock . activateApplication ( true ) ;
} catch ( ex ) {
}
2013-02-23 06:32:30 +00:00
# endif // XP_MACOSX
2011-02-03 19:54:10 +00:00
return true ;
}
2013-07-29 16:33:44 +00:00
function Blur ( )
{
// On non-remote reftests, this will transfer focus to the dummy window
// we created to hold focus for non-needs-focus tests. Buggy tests
// (ones which require focus but don't request needs-focus) will then
// fail.
gContainingWindow . blur ( ) ;
}
2007-02-12 02:21:18 +00:00
function StartCurrentTest ( )
{
2010-12-20 01:37:43 +00:00
gTestLog = [ ] ;
2007-05-08 10:21:22 +00:00
// make sure we don't run tests that are expected to kill the browser
2010-07-13 23:04:29 +00:00
while ( gURLs . length > 0 ) {
var test = gURLs [ 0 ] ;
2016-02-05 20:44:20 +00:00
logger . testStart ( test . identifier ) ;
2010-07-13 23:04:29 +00:00
if ( test . expected == EXPECTED _DEATH ) {
++ gTestResults . Skip ;
2016-02-05 20:44:20 +00:00
logger . testEnd ( test . identifier , "SKIP" ) ;
2010-07-13 23:04:29 +00:00
gURLs . shift ( ) ;
2011-02-03 19:54:10 +00:00
} else if ( test . needsFocus && ! Focus ( ) ) {
2012-04-10 17:56:59 +00:00
// FIXME: Marking this as a known fail is dangerous! What
// if it starts failing all the time?
2011-02-03 19:54:10 +00:00
++ gTestResults . Skip ;
2016-02-05 20:44:20 +00:00
logger . testEnd ( test . identifier , "SKIP" , null , "(COULDN'T GET FOCUS)" ) ;
2011-02-03 19:54:10 +00:00
gURLs . shift ( ) ;
2010-07-13 23:04:29 +00:00
} else if ( test . slow && ! gRunSlowTests ) {
++ gTestResults . Slow ;
2016-02-05 20:44:20 +00:00
logger . testEnd ( test . identifier , "SKIP" , null , "(SLOW)" ) ;
2010-07-13 23:04:29 +00:00
gURLs . shift ( ) ;
} else {
break ;
}
2007-05-08 10:21:22 +00:00
}
2016-01-15 23:30:23 +00:00
if ( ( gURLs . length == 0 && gRepeat == 0 ) ||
( gRunUntilFailure && HasUnexpectedResult ( ) ) ) {
2012-04-10 17:56:59 +00:00
RestoreChangedPreferences ( ) ;
2007-02-12 02:21:18 +00:00
DoneTests ( ) ;
2016-01-15 23:30:23 +00:00
} else if ( gURLs . length == 0 && gRepeat > 0 ) {
// Repeat
gRepeat -- ;
StartTests ( ) ;
} else {
2015-06-04 17:44:55 +00:00
if ( gURLs [ 0 ] . chaosMode ) {
gWindowUtils . enterChaosMode ( ) ;
}
2013-07-29 16:33:44 +00:00
if ( ! gURLs [ 0 ] . needsFocus ) {
Blur ( ) ;
}
2008-07-19 20:54:47 +00:00
var currentTest = gTotalTests - gURLs . length ;
2011-12-15 12:41:40 +00:00
gContainingWindow . document . title = "reftest: " + currentTest + " / " + gTotalTests +
2008-07-19 20:54:47 +00:00
" (" + Math . floor ( 100 * ( currentTest / gTotalTests ) ) + "%)" ;
2008-12-17 02:15:38 +00:00
StartCurrentURI ( 1 ) ;
2008-07-19 20:54:47 +00:00
}
2007-02-12 02:21:18 +00:00
}
function StartCurrentURI ( aState )
2006-09-05 21:50:54 +00:00
{
2007-02-12 02:21:18 +00:00
gState = aState ;
2008-10-19 20:27:46 +00:00
gCurrentURL = gURLs [ 0 ] [ "url" + aState ] . spec ;
2008-12-08 00:48:36 +00:00
2012-04-10 17:56:59 +00:00
RestoreChangedPreferences ( ) ;
2016-12-14 07:44:39 +00:00
var prefs = Components . classes [ "@mozilla.org/preferences-service;1" ] .
getService ( Components . interfaces . nsIPrefBranch ) ;
2012-04-10 17:56:59 +00:00
var prefSettings = gURLs [ 0 ] [ "prefSettings" + aState ] ;
if ( prefSettings . length > 0 ) {
var badPref = undefined ;
try {
prefSettings . forEach ( function ( ps ) {
var oldVal ;
if ( ps . type == PREF _BOOLEAN ) {
try {
oldVal = prefs . getBoolPref ( ps . name ) ;
} catch ( e ) {
badPref = "boolean preference '" + ps . name + "'" ;
throw "bad pref" ;
}
} else if ( ps . type == PREF _STRING ) {
try {
oldVal = prefs . getCharPref ( ps . name ) ;
} catch ( e ) {
badPref = "string preference '" + ps . name + "'" ;
throw "bad pref" ;
}
} else if ( ps . type == PREF _INTEGER ) {
try {
oldVal = prefs . getIntPref ( ps . name ) ;
} catch ( e ) {
badPref = "integer preference '" + ps . name + "'" ;
throw "bad pref" ;
}
} else {
throw "internal error - unknown preference type" ;
}
if ( oldVal != ps . value ) {
gPrefsToRestore . push ( { name : ps . name ,
type : ps . type ,
value : oldVal } ) ;
var value = ps . value ;
if ( ps . type == PREF _BOOLEAN ) {
prefs . setBoolPref ( ps . name , value ) ;
} else if ( ps . type == PREF _STRING ) {
prefs . setCharPref ( ps . name , value ) ;
value = '"' + value + '"' ;
} else if ( ps . type == PREF _INTEGER ) {
prefs . setIntPref ( ps . name , value ) ;
}
2016-02-05 20:44:20 +00:00
logger . info ( "SET PREFERENCE pref(" + ps . name + "," + value + ")" ) ;
2012-04-10 17:56:59 +00:00
}
} ) ;
} catch ( e ) {
if ( e == "bad pref" ) {
var test = gURLs [ 0 ] ;
if ( test . expected == EXPECTED _FAIL ) {
2016-02-05 20:44:20 +00:00
logger . testEnd ( test . identifier , "FAIL" , "FAIL" ,
"(SKIPPED; " + badPref + " not known or wrong type)" ) ;
2012-04-10 17:56:59 +00:00
++ gTestResults . Skip ;
} else {
2016-02-05 20:44:20 +00:00
logger . testEnd ( test . identifier , "FAIL" , "PASS" ,
badPref + " not known or wrong type" ) ;
2012-04-10 17:56:59 +00:00
++ gTestResults . UnexpectedFail ;
}
2016-02-05 20:44:20 +00:00
// skip the test that had a bad preference
gURLs . shift ( ) ;
StartCurrentTest ( ) ;
return ;
2012-04-10 17:56:59 +00:00
} else {
throw e ;
}
}
}
if ( prefSettings . length == 0 &&
2011-12-29 00:24:48 +00:00
gURICanvases [ gCurrentURL ] &&
2009-08-20 07:56:22 +00:00
( gURLs [ 0 ] . type == TYPE _REFTEST _EQUAL ||
gURLs [ 0 ] . type == TYPE _REFTEST _NOTEQUAL ) &&
2009-01-08 21:50:21 +00:00
gURLs [ 0 ] . maxAsserts == 0 ) {
2010-12-20 01:37:42 +00:00
// Pretend the document loaded --- RecordResult will notice
2008-12-08 00:48:36 +00:00
// there's already a canvas for this URL
2011-12-15 12:41:40 +00:00
gContainingWindow . setTimeout ( RecordResult , 0 ) ;
2008-12-08 00:48:36 +00:00
} else {
2011-09-30 13:47:02 +00:00
var currentTest = gTotalTests - gURLs . length ;
2016-02-05 20:44:20 +00:00
// Log this to preserve the same overall log format,
// should be removed if the format is updated
2016-04-27 20:56:09 +00:00
gDumpFn ( "REFTEST TEST-LOAD | " + gCurrentURL + " | " + currentTest + " / " + gTotalTests +
" (" + Math . floor ( 100 * ( currentTest / gTotalTests ) ) + "%)\n" ) ;
2016-02-05 20:44:20 +00:00
TestBuffer ( "START " + gCurrentURL ) ;
2011-02-03 19:54:10 +00:00
var type = gURLs [ 0 ] . type
if ( TYPE _SCRIPT == type ) {
SendLoadScriptTest ( gCurrentURL , gLoadTimeout ) ;
2017-09-06 16:54:29 +00:00
} else if ( TYPE _PRINT == type ) {
SendLoadPrintTest ( gCurrentURL , gLoadTimeout ) ;
2011-02-03 19:54:10 +00:00
} else {
SendLoadTest ( type , gCurrentURL , gLoadTimeout ) ;
}
2008-12-08 00:48:36 +00:00
}
2006-09-05 21:50:54 +00:00
}
function DoneTests ( )
{
2017-08-30 08:50:27 +00:00
logger . suiteEnd ( { 'results' : gTestResults } ) ;
2017-09-23 15:07:03 +00:00
gSuiteStarted = false
2016-02-05 20:44:20 +00:00
logger . info ( "Slowest test took " + gSlowestTestTime + "ms (" + gSlowestTestURL + ")" ) ;
logger . info ( "Total canvas count = " + gRecycledCanvases . length ) ;
2016-07-11 01:11:08 +00:00
if ( gFailedUseWidgetLayers ) {
LogWidgetLayersFailure ( ) ;
}
2016-02-05 20:44:20 +00:00
2009-04-15 20:19:35 +00:00
function onStopped ( ) {
2011-12-20 12:46:10 +00:00
let appStartup = CC [ "@mozilla.org/toolkit/app-startup;1" ] . getService ( CI . nsIAppStartup ) ;
appStartup . quit ( CI . nsIAppStartup . eForceQuit ) ;
2009-04-15 20:19:35 +00:00
}
2012-08-10 18:25:20 +00:00
if ( gServer ) {
2009-04-15 20:19:35 +00:00
gServer . stop ( onStopped ) ;
2012-08-10 18:25:20 +00:00
}
else {
2009-04-15 20:19:35 +00:00
onStopped ( ) ;
2012-08-10 18:25:20 +00:00
}
2006-09-05 21:50:54 +00:00
}
2008-12-17 02:15:38 +00:00
function UpdateCanvasCache ( url , canvas )
2008-12-08 00:48:36 +00:00
{
2008-12-17 02:15:38 +00:00
var spec = url . spec ;
2008-12-08 00:48:36 +00:00
-- gURIUseCounts [ spec ] ;
2009-09-22 20:01:11 +00:00
2017-02-26 03:57:01 +00:00
if ( gURIUseCounts [ spec ] == 0 ) {
2008-12-08 00:48:36 +00:00
ReleaseCanvas ( canvas ) ;
delete gURICanvases [ spec ] ;
} else if ( gURIUseCounts [ spec ] > 0 ) {
gURICanvases [ spec ] = canvas ;
} else {
throw "Use counts were computed incorrectly" ;
}
}
2010-09-05 03:39:35 +00:00
// Recompute drawWindow flags for every drawWindow operation.
// We have to do this every time since our window can be
// asynchronously resized (e.g. by the window manager, to make
// it fit on screen) at unpredictable times.
// Fortunately this is pretty cheap.
2012-07-28 10:31:26 +00:00
function DoDrawWindow ( ctx , x , y , w , h )
2010-06-28 00:32:16 +00:00
{
2010-09-05 03:39:35 +00:00
var flags = ctx . DRAWWINDOW _DRAW _CARET | ctx . DRAWWINDOW _DRAW _VIEW ;
var testRect = gBrowser . getBoundingClientRect ( ) ;
2011-07-12 22:10:10 +00:00
if ( gIgnoreWindowSize ||
( 0 <= testRect . left &&
0 <= testRect . top &&
2011-12-15 12:41:40 +00:00
gContainingWindow . innerWidth >= testRect . right &&
gContainingWindow . innerHeight >= testRect . bottom ) ) {
2010-09-05 03:39:35 +00:00
// We can use the window's retained layer manager
// because the window is big enough to display the entire
// browser element
flags |= ctx . DRAWWINDOW _USE _WIDGET _LAYERS ;
2011-02-03 19:54:10 +00:00
} else if ( gBrowserIsRemote ) {
2016-02-05 20:44:20 +00:00
logger . error ( gCurrentURL + " | can't drawWindow remote content" ) ;
2011-02-03 19:54:10 +00:00
++ gTestResults . Exception ;
2010-09-05 03:39:35 +00:00
}
if ( gDrawWindowFlags != flags ) {
// Every time the flags change, dump the new state.
gDrawWindowFlags = flags ;
var flagsStr = "DRAWWINDOW_DRAW_CARET | DRAWWINDOW_DRAW_VIEW" ;
if ( flags & ctx . DRAWWINDOW _USE _WIDGET _LAYERS ) {
flagsStr += " | DRAWWINDOW_USE_WIDGET_LAYERS" ;
} else {
// Output a special warning because we need to be able to detect
// this whenever it happens.
2016-07-11 01:11:08 +00:00
LogWidgetLayersFailure ( ) ;
gFailedUseWidgetLayers = true ;
2010-06-28 00:32:16 +00:00
}
2016-02-05 20:44:20 +00:00
logger . info ( "drawWindow flags = " + flagsStr +
"; window size = " + gContainingWindow . innerWidth + "," + gContainingWindow . innerHeight +
"; test browser size = " + testRect . width + "," + testRect . height ) ;
2010-06-28 00:32:16 +00:00
}
2016-02-05 20:44:20 +00:00
TestBuffer ( "DoDrawWindow " + x + "," + y + "," + w + "," + h ) ;
2011-12-15 12:41:40 +00:00
ctx . drawWindow ( gContainingWindow , x , y , w , h , "rgb(255,255,255)" ,
2010-06-28 00:32:16 +00:00
gDrawWindowFlags ) ;
}
2009-01-06 01:15:13 +00:00
function InitCurrentCanvasWithSnapshot ( )
{
2016-02-05 20:44:20 +00:00
TestBuffer ( "Initializing canvas snapshot" ) ;
2011-02-03 19:54:10 +00:00
2017-09-06 16:54:29 +00:00
if ( gURLs [ 0 ] . type == TYPE _LOAD || gURLs [ 0 ] . type == TYPE _SCRIPT || gURLs [ 0 ] . type == TYPE _PRINT ) {
2010-06-28 00:32:16 +00:00
// We don't want to snapshot this kind of test
2011-02-02 16:40:17 +00:00
return false ;
2010-06-28 00:32:16 +00:00
}
2010-12-20 01:37:43 +00:00
if ( ! gCurrentCanvas ) {
gCurrentCanvas = AllocateCanvas ( ) ;
}
2009-01-06 01:15:13 +00:00
2012-07-28 10:31:26 +00:00
var ctx = gCurrentCanvas . getContext ( "2d" ) ;
DoDrawWindow ( ctx , 0 , 0 , gCurrentCanvas . width , gCurrentCanvas . height ) ;
2011-02-02 16:40:17 +00:00
return true ;
2009-01-06 01:15:13 +00:00
}
2011-02-03 19:54:10 +00:00
function UpdateCurrentCanvasForInvalidation ( rects )
2009-01-06 01:15:13 +00:00
{
2016-02-05 20:44:20 +00:00
TestBuffer ( "Updating canvas for invalidation" ) ;
2009-01-06 01:15:13 +00:00
2011-02-03 19:54:10 +00:00
if ( ! gCurrentCanvas ) {
2010-06-28 00:32:16 +00:00
return ;
2011-02-03 19:54:10 +00:00
}
2010-06-28 00:32:16 +00:00
2009-01-06 01:15:13 +00:00
var ctx = gCurrentCanvas . getContext ( "2d" ) ;
2011-02-03 19:54:10 +00:00
for ( var i = 0 ; i < rects . length ; ++ i ) {
var r = rects [ i ] ;
2010-09-05 03:39:32 +00:00
// Set left/top/right/bottom to pixel boundaries
var left = Math . floor ( r . left ) ;
var top = Math . floor ( r . top ) ;
var right = Math . ceil ( r . right ) ;
var bottom = Math . ceil ( r . bottom ) ;
2009-01-06 01:15:13 +00:00
2014-12-10 12:50:47 +00:00
// Clamp the values to the canvas size
left = Math . max ( 0 , Math . min ( left , gCurrentCanvas . width ) ) ;
top = Math . max ( 0 , Math . min ( top , gCurrentCanvas . height ) ) ;
right = Math . max ( 0 , Math . min ( right , gCurrentCanvas . width ) ) ;
bottom = Math . max ( 0 , Math . min ( bottom , gCurrentCanvas . height ) ) ;
2009-01-06 01:15:13 +00:00
ctx . save ( ) ;
ctx . translate ( left , top ) ;
2012-07-28 10:31:26 +00:00
DoDrawWindow ( ctx , left , top , right - left , bottom - top ) ;
2009-01-06 01:15:13 +00:00
ctx . restore ( ) ;
}
}
2013-06-18 07:59:46 +00:00
function UpdateWholeCurrentCanvasForInvalidation ( )
{
2016-02-05 20:44:20 +00:00
TestBuffer ( "Updating entire canvas for invalidation" ) ;
2013-06-18 07:59:46 +00:00
if ( ! gCurrentCanvas ) {
return ;
}
var ctx = gCurrentCanvas . getContext ( "2d" ) ;
DoDrawWindow ( ctx , 0 , 0 , gCurrentCanvas . width , gCurrentCanvas . height ) ;
}
2017-09-06 16:54:29 +00:00
function RecordResult ( testRunTime , errorMsg , typeSpecificResults )
2006-09-05 21:50:54 +00:00
{
2016-02-05 20:44:20 +00:00
TestBuffer ( "RecordResult fired" ) ;
2010-12-20 01:37:43 +00:00
2008-04-30 00:39:45 +00:00
// Keep track of which test was slowest, and how long it took.
2011-02-03 19:54:10 +00:00
if ( testRunTime > gSlowestTestTime ) {
gSlowestTestTime = testRunTime ;
2008-12-08 00:48:36 +00:00
gSlowestTestURL = gCurrentURL ;
2008-04-30 00:39:45 +00:00
}
2009-08-20 07:56:22 +00:00
// Not 'const ...' because of 'EXPECTED_*' value dependency.
var outputs = { } ;
outputs [ EXPECTED _PASS ] = {
2016-02-05 20:44:20 +00:00
true : { s : [ "PASS" , "PASS" ] , n : "Pass" } ,
false : { s : [ "FAIL" , "PASS" ] , n : "UnexpectedFail" }
2009-08-20 07:56:22 +00:00
} ;
outputs [ EXPECTED _FAIL ] = {
2016-02-05 20:44:20 +00:00
true : { s : [ "PASS" , "FAIL" ] , n : "UnexpectedPass" } ,
false : { s : [ "FAIL" , "FAIL" ] , n : "KnownFail" }
2009-08-20 07:56:22 +00:00
} ;
outputs [ EXPECTED _RANDOM ] = {
2016-02-05 20:44:20 +00:00
true : { s : [ "PASS" , "PASS" ] , n : "Random" } ,
false : { s : [ "FAIL" , "FAIL" ] , n : "Random" }
2009-08-20 07:56:22 +00:00
} ;
2017-06-02 13:28:33 +00:00
// for EXPECTED_FUZZY we need special handling because we can have
// Pass, UnexpectedPass, or UnexpectedFail
2011-12-19 14:02:53 +00:00
2009-08-20 07:56:22 +00:00
var output ;
2016-02-05 20:44:20 +00:00
var extra ;
2009-08-20 07:56:22 +00:00
if ( gURLs [ 0 ] . type == TYPE _LOAD ) {
2008-12-02 12:35:24 +00:00
++ gTestResults . LoadOnly ;
2017-06-16 19:08:45 +00:00
logger . testStatus ( gURLs [ 0 ] . identifier , "(LOAD ONLY)" , "PASS" , "PASS" ) ;
2010-06-18 15:29:52 +00:00
gCurrentCanvas = null ;
2009-01-08 21:50:21 +00:00
FinishTestItem ( ) ;
2007-10-03 21:27:04 +00:00
return ;
}
2017-09-06 16:54:29 +00:00
if ( gURLs [ 0 ] . type == TYPE _PRINT ) {
switch ( gState ) {
case 1 :
// First document has been loaded.
gTestPrintOutput = typeSpecificResults ;
// Proceed to load the second document.
CleanUpCrashDumpFiles ( ) ;
StartCurrentURI ( 2 ) ;
break ;
case 2 :
var pathToTestPdf = gTestPrintOutput ;
var pathToRefPdf = typeSpecificResults ;
comparePdfs ( pathToTestPdf , pathToRefPdf , function ( error , results ) {
var expected = gURLs [ 0 ] . expected ;
// TODO: We should complain here if results is empty!
// (If it's empty, we'll spuriously succeed, regardless of
// our expectations)
if ( error ) {
output = outputs [ expected ] [ false ] ;
extra = { status _msg : output . n } ;
++ gTestResults [ output . n ] ;
logger . testEnd ( gURLs [ 0 ] . identifier , output . s [ 0 ] , output . s [ 1 ] ,
error . message , null , extra ) ;
} else {
var outputPair = outputs [ expected ] ;
if ( expected === EXPECTED _FAIL ) {
var failureResults = results . filter ( function ( result ) { return ! result . passed } ) ;
if ( failureResults . length > 0 ) {
// We got an expected failure. Let's get rid of the
// passes from the results so we don't trigger
// TEST_UNEXPECTED_PASS logging for those.
results = failureResults ;
}
// (else, we expected a failure but got none!
// Leave results untouched so we can log them.)
}
results . forEach ( function ( result ) {
output = outputPair [ result . passed ] ;
var extra = { status _msg : output . n } ;
++ gTestResults [ output . n ] ;
logger . testEnd ( gURLs [ 0 ] . identifier , output . s [ 0 ] , output . s [ 1 ] ,
result . description , null , extra ) ;
} ) ;
}
FinishTestItem ( ) ;
} ) ;
break ;
default :
throw "Unexpected state." ;
}
return ;
}
2009-08-20 07:56:22 +00:00
if ( gURLs [ 0 ] . type == TYPE _SCRIPT ) {
2011-02-03 19:54:10 +00:00
var expected = gURLs [ 0 ] . expected ;
2009-08-20 07:56:22 +00:00
2011-02-03 19:54:10 +00:00
if ( errorMsg ) {
2009-08-20 07:56:22 +00:00
// Force an unexpected failure to alert the test author to fix the test.
expected = EXPECTED _PASS ;
2017-09-06 16:54:29 +00:00
} else if ( typeSpecificResults . length == 0 ) {
2011-02-03 19:54:10 +00:00
// This failure may be due to a JavaScript Engine bug causing
// early termination of the test. If we do not allow silent
// failure, report an error.
if ( ! gURLs [ 0 ] . allowSilentFail )
errorMsg = "No test results reported. (SCRIPT)\n" ;
else
2016-02-05 20:44:20 +00:00
logger . info ( "An expected silent failure occurred" ) ;
2009-08-20 07:56:22 +00:00
}
2011-02-03 19:54:10 +00:00
if ( errorMsg ) {
2009-08-20 07:56:22 +00:00
output = outputs [ expected ] [ false ] ;
2016-02-05 20:44:20 +00:00
extra = { status _msg : output . n } ;
2009-08-20 07:56:22 +00:00
++ gTestResults [ output . n ] ;
2017-06-16 19:08:45 +00:00
logger . testStatus ( gURLs [ 0 ] . identifier , errorMsg , output . s [ 0 ] , output . s [ 1 ] , null , null , extra ) ;
2009-08-20 07:56:22 +00:00
FinishTestItem ( ) ;
return ;
}
2017-09-06 16:54:29 +00:00
var anyFailed = typeSpecificResults . some ( function ( result ) { return ! result . passed ; } ) ;
2009-08-20 07:56:22 +00:00
var outputPair ;
if ( anyFailed && expected == EXPECTED _FAIL ) {
// If we're marked as expected to fail, and some (but not all) tests
// passed, treat those tests as though they were marked random
// (since we can't tell whether they were really intended to be
// marked failing or not).
outputPair = { true : outputs [ EXPECTED _RANDOM ] [ true ] ,
false : outputs [ expected ] [ false ] } ;
} else {
outputPair = outputs [ expected ] ;
}
var index = 0 ;
2017-09-06 16:54:29 +00:00
typeSpecificResults . forEach ( function ( result ) {
2009-08-20 07:56:22 +00:00
var output = outputPair [ result . passed ] ;
2016-02-05 20:44:20 +00:00
var extra = { status _msg : output . n } ;
2009-08-20 07:56:22 +00:00
++ gTestResults [ output . n ] ;
2017-06-16 19:08:45 +00:00
logger . testStatus ( gURLs [ 0 ] . identifier , result . description + " item " + ( ++ index ) ,
output . s [ 0 ] , output . s [ 1 ] , null , null , extra ) ;
2009-08-20 07:56:22 +00:00
} ) ;
2010-12-20 01:37:43 +00:00
if ( anyFailed && expected == EXPECTED _PASS ) {
2016-02-05 20:44:20 +00:00
FlushTestBuffer ( ) ;
2010-12-20 01:37:43 +00:00
}
2009-08-20 07:56:22 +00:00
FinishTestItem ( ) ;
return ;
}
2007-10-03 21:27:04 +00:00
2012-04-10 17:56:59 +00:00
if ( gURLs [ 0 ] [ "prefSettings" + gState ] . length == 0 &&
2011-12-29 00:24:48 +00:00
gURICanvases [ gCurrentURL ] ) {
2009-01-06 01:15:13 +00:00
gCurrentCanvas = gURICanvases [ gCurrentURL ] ;
2008-12-08 00:48:36 +00:00
}
2011-02-03 19:54:10 +00:00
if ( gCurrentCanvas == null ) {
2016-02-05 20:44:20 +00:00
logger . error ( gCurrentURL , "program error managing snapshots" ) ;
2011-02-03 19:54:10 +00:00
++ gTestResults . Exception ;
}
2008-12-17 02:15:38 +00:00
if ( gState == 1 ) {
2009-01-06 01:15:13 +00:00
gCanvas1 = gCurrentCanvas ;
2008-12-08 00:48:36 +00:00
} else {
2009-01-06 01:15:13 +00:00
gCanvas2 = gCurrentCanvas ;
2008-12-08 00:48:36 +00:00
}
2009-01-06 01:15:13 +00:00
gCurrentCanvas = null ;
2008-10-15 20:49:42 +00:00
2011-02-23 17:45:09 +00:00
ResetRenderingState ( ) ;
2007-08-03 02:28:55 +00:00
2006-09-05 21:50:54 +00:00
switch ( gState ) {
2008-12-17 02:15:38 +00:00
case 1 :
2007-08-03 02:28:55 +00:00
// First document has been loaded.
// Proceed to load the second document.
2006-09-05 21:50:54 +00:00
2011-04-26 03:02:38 +00:00
CleanUpCrashDumpFiles ( ) ;
2008-12-17 02:15:38 +00:00
StartCurrentURI ( 2 ) ;
2006-09-05 21:50:54 +00:00
break ;
2008-12-17 02:15:38 +00:00
case 2 :
2007-03-01 06:26:23 +00:00
// Both documents have been loaded. Compare the renderings and see
// if the comparison result matches the expected result specified
// in the manifest.
2007-08-03 02:28:55 +00:00
// number of different pixels
var differences ;
2007-03-01 06:26:23 +00:00
// whether the two renderings match:
2007-08-03 02:28:55 +00:00
var equal ;
2011-12-19 14:02:53 +00:00
var maxDifference = { } ;
2017-06-02 13:28:33 +00:00
// whether the allowed fuzziness from the annotations is exceeded
// by the actual comparison results
var fuzz _exceeded = false ;
2011-12-19 14:02:53 +00:00
2011-12-19 14:02:53 +00:00
differences = gWindowUtils . compareCanvases ( gCanvas1 , gCanvas2 , maxDifference ) ;
2011-12-19 14:02:47 +00:00
equal = ( differences == 0 ) ;
2011-12-19 14:02:53 +00:00
2017-06-02 13:28:33 +00:00
if ( maxDifference . value > 0 && equal ) {
throw "Inconsistent result from compareCanvases." ;
}
2012-01-17 18:08:38 +00:00
// what is expected on this platform (PASS, FAIL, or RANDOM)
var expected = gURLs [ 0 ] . expected ;
2011-12-19 14:02:53 +00:00
2017-06-02 13:28:33 +00:00
if ( expected == EXPECTED _FUZZY ) {
logger . info ( ` REFTEST fuzzy test ` +
` ( ${ gURLs [ 0 ] . fuzzyMinDelta } , ${ gURLs [ 0 ] . fuzzyMinPixels } ) <= ` +
` ( ${ maxDifference . value } , ${ differences } ) <= ` +
` ( ${ gURLs [ 0 ] . fuzzyMaxDelta } , ${ gURLs [ 0 ] . fuzzyMaxPixels } ) ` ) ;
fuzz _exceeded = maxDifference . value > gURLs [ 0 ] . fuzzyMaxDelta ||
differences > gURLs [ 0 ] . fuzzyMaxPixels ;
equal = ! fuzz _exceeded &&
maxDifference . value >= gURLs [ 0 ] . fuzzyMinDelta &&
differences >= gURLs [ 0 ] . fuzzyMinPixels ;
2011-12-19 14:02:53 +00:00
}
2015-03-11 18:51:59 +00:00
var failedExtraCheck = gFailedNoPaint || gFailedOpaqueLayer || gFailedAssignedLayer ;
2011-12-19 14:02:53 +00:00
// whether the comparison result matches what is in the manifest
2015-03-11 18:51:59 +00:00
var test _passed = ( equal == ( gURLs [ 0 ] . type == TYPE _REFTEST _EQUAL ) ) && ! failedExtraCheck ;
2011-12-19 14:02:53 +00:00
2017-06-02 13:28:33 +00:00
if ( expected != EXPECTED _FUZZY ) {
output = outputs [ expected ] [ test _passed ] ;
} else if ( test _passed ) {
output = { s : [ "PASS" , "PASS" ] , n : "Pass" } ;
} else if ( gURLs [ 0 ] . type == TYPE _REFTEST _EQUAL &&
! failedExtraCheck &&
! fuzz _exceeded ) {
// If we get here, that means we had an '==' type test where
// at least one of the actual difference values was below the
// allowed range, but nothing else was wrong. So let's produce
// UNEXPECTED-PASS in this scenario. Also, if we enter this
// branch, 'equal' must be false so let's assert that to guard
// against logic errors.
if ( equal ) {
throw "Logic error in reftest.jsm fuzzy test handling!" ;
}
output = { s : [ "PASS" , "FAIL" ] , n : "UnexpectedPass" } ;
} else {
// In all other cases we fail the test
output = { s : [ "FAIL" , "PASS" ] , n : "UnexpectedFail" } ;
}
2016-02-05 20:44:20 +00:00
extra = { status _msg : output . n } ;
2009-08-20 07:56:22 +00:00
++ gTestResults [ output . n ] ;
2009-05-14 14:17:45 +00:00
2015-03-11 18:51:59 +00:00
// It's possible that we failed both an "extra check" and the normal comparison, but we don't
// have a way to annotate these separately, so just print an error for the extra check failures.
if ( failedExtraCheck ) {
var failures = [ ] ;
if ( gFailedNoPaint ) {
failures . push ( "failed reftest-no-paint" ) ;
}
// The gFailed*Messages arrays will contain messages from both the test and the reference.
if ( gFailedOpaqueLayer ) {
failures . push ( "failed reftest-opaque-layer: " + gFailedOpaqueLayerMessages . join ( ", " ) ) ;
}
if ( gFailedAssignedLayer ) {
failures . push ( "failed reftest-assigned-layer: " + gFailedAssignedLayerMessages . join ( ", " ) ) ;
}
var failureString = failures . join ( ", " ) ;
2017-06-16 19:08:45 +00:00
logger . testStatus ( gURLs [ 0 ] . identifier , failureString , output . s [ 0 ] , output . s [ 1 ] , null , null , extra ) ;
2013-06-07 05:10:31 +00:00
} else {
2017-09-21 15:28:24 +00:00
var message = "image comparison, max difference: " + maxDifference . value +
", number of differing pixels: " + differences ;
2013-06-07 05:10:31 +00:00
if ( ! test _passed && expected == EXPECTED _PASS ||
! test _passed && expected == EXPECTED _FUZZY ||
test _passed && expected == EXPECTED _FAIL ) {
if ( ! equal ) {
2016-02-05 20:44:20 +00:00
extra . max _difference = maxDifference . value ;
extra . differences = differences ;
2016-09-27 21:54:50 +00:00
var image1 = gCanvas1 . toDataURL ( ) ;
var image2 = gCanvas2 . toDataURL ( ) ;
2016-08-08 16:48:39 +00:00
extra . reftest _screenshots = [
2016-09-27 21:54:50 +00:00
{ url : gURLs [ 0 ] . identifier [ 0 ] ,
screenshot : image1 . slice ( image1 . indexOf ( "," ) + 1 ) } ,
2016-08-08 16:48:39 +00:00
gURLs [ 0 ] . identifier [ 1 ] ,
2016-09-27 21:54:50 +00:00
{ url : gURLs [ 0 ] . identifier [ 2 ] ,
screenshot : image2 . slice ( image2 . indexOf ( "," ) + 1 ) }
2016-08-08 16:48:39 +00:00
] ;
2016-09-27 21:54:50 +00:00
extra . image1 = image1 ;
extra . image2 = image2 ;
2013-06-07 05:10:31 +00:00
} else {
2017-02-23 22:34:27 +00:00
var image1 = gCanvas1 . toDataURL ( ) ;
extra . reftest _screenshots = [
{ url : gURLs [ 0 ] . identifier [ 0 ] ,
screenshot : image1 . slice ( image1 . indexOf ( "," ) + 1 ) }
] ;
extra . image1 = image1 ;
2013-06-07 05:10:31 +00:00
}
2007-11-26 08:36:53 +00:00
}
2017-06-16 19:08:45 +00:00
logger . testStatus ( gURLs [ 0 ] . identifier , message , output . s [ 0 ] , output . s [ 1 ] , null , null , extra ) ;
2015-03-11 18:51:59 +00:00
2017-02-26 03:57:01 +00:00
if ( gNoCanvasCache ) {
ReleaseCanvas ( gCanvas1 ) ;
ReleaseCanvas ( gCanvas2 ) ;
} else {
if ( gURLs [ 0 ] . prefSettings1 . length == 0 ) {
UpdateCanvasCache ( gURLs [ 0 ] . url1 , gCanvas1 ) ;
}
if ( gURLs [ 0 ] . prefSettings2 . length == 0 ) {
UpdateCanvasCache ( gURLs [ 0 ] . url2 , gCanvas2 ) ;
}
2015-03-11 18:51:59 +00:00
}
2013-06-07 05:10:31 +00:00
}
2012-09-14 21:12:34 +00:00
2014-06-20 00:51:00 +00:00
if ( ( ! test _passed && expected == EXPECTED _PASS ) || ( test _passed && expected == EXPECTED _FAIL ) ) {
2016-02-05 20:44:20 +00:00
FlushTestBuffer ( ) ;
2010-12-20 01:37:43 +00:00
}
2011-04-26 03:02:38 +00:00
CleanUpCrashDumpFiles ( ) ;
2009-01-08 21:50:21 +00:00
FinishTestItem ( ) ;
2006-09-05 21:50:54 +00:00
break ;
default :
2007-07-18 21:32:50 +00:00
throw "Unexpected state." ;
2006-09-05 21:50:54 +00:00
}
}
2007-02-13 00:54:02 +00:00
2011-02-03 19:54:10 +00:00
function LoadFailed ( why )
2007-02-13 00:54:02 +00:00
{
2008-12-02 12:35:24 +00:00
++ gTestResults . FailedLoad ;
2014-04-17 00:13:38 +00:00
// Once bug 896840 is fixed, this can go away, but for now it will give log
// output that is TBPL starable for bug 789751 and bug 720452.
if ( ! why ) {
2016-02-05 20:44:20 +00:00
logger . error ( "load failed with unknown reason" ) ;
2014-04-17 00:13:38 +00:00
}
2017-06-16 19:08:45 +00:00
logger . testStatus ( gURLs [ 0 ] . identifier , "load failed: " + why , "FAIL" , "PASS" ) ;
2016-02-05 20:44:20 +00:00
FlushTestBuffer ( ) ;
2009-01-08 21:50:21 +00:00
FinishTestItem ( ) ;
}
2011-04-26 03:02:38 +00:00
function RemoveExpectedCrashDumpFiles ( )
{
if ( gExpectingProcessCrash ) {
2015-06-05 09:23:14 +00:00
for ( let crashFilename of gExpectedCrashDumpFiles ) {
2011-04-26 03:02:38 +00:00
let file = gCrashDumpDir . clone ( ) ;
file . append ( crashFilename ) ;
if ( file . exists ( ) ) {
file . remove ( false ) ;
}
}
}
gExpectedCrashDumpFiles . length = 0 ;
}
function FindUnexpectedCrashDumpFiles ( )
{
if ( ! gCrashDumpDir . exists ( ) ) {
return ;
}
let entries = gCrashDumpDir . directoryEntries ;
if ( ! entries ) {
return ;
}
let foundCrashDumpFile = false ;
while ( entries . hasMoreElements ( ) ) {
let file = entries . getNext ( ) . QueryInterface ( CI . nsIFile ) ;
let path = String ( file . path ) ;
if ( path . match ( /\.(dmp|extra)$/ ) && ! gUnexpectedCrashDumpFiles [ path ] ) {
if ( ! foundCrashDumpFile ) {
2011-12-05 03:06:42 +00:00
++ gTestResults . UnexpectedFail ;
2011-04-26 03:02:38 +00:00
foundCrashDumpFile = true ;
2017-07-18 17:10:29 +00:00
if ( gCurrentURL ) {
2017-06-16 19:08:45 +00:00
logger . testStatus ( gURLs [ 0 ] . identifier , "crash-check" , "FAIL" , "PASS" , "This test left crash dumps behind, but we weren't expecting it to!" ) ;
2017-07-18 17:10:29 +00:00
} else {
logger . error ( "Harness startup left crash dumps behind, but we weren't expecting it to!" ) ;
}
2011-04-26 03:02:38 +00:00
}
2016-02-05 20:44:20 +00:00
logger . info ( "Found unexpected crash dump file " + path ) ;
2011-04-26 03:02:38 +00:00
gUnexpectedCrashDumpFiles [ path ] = true ;
}
}
}
2017-04-07 21:46:08 +00:00
function RemovePendingCrashDumpFiles ( )
{
if ( ! gPendingCrashDumpDir . exists ( ) ) {
return ;
}
let entries = gPendingCrashDumpDir . directoryEntries ;
while ( entries . hasMoreElements ( ) ) {
let file = entries . getNext ( ) . QueryInterface ( CI . nsIFile ) ;
if ( file . isFile ( ) ) {
file . remove ( false ) ;
logger . info ( "This test left pending crash dumps; deleted " + file . path ) ;
}
}
}
2011-04-26 03:02:38 +00:00
function CleanUpCrashDumpFiles ( )
{
RemoveExpectedCrashDumpFiles ( ) ;
FindUnexpectedCrashDumpFiles ( ) ;
2017-04-07 21:46:08 +00:00
if ( gCleanupPendingCrashes ) {
RemovePendingCrashDumpFiles ( ) ;
}
2011-04-26 03:02:38 +00:00
gExpectingProcessCrash = false ;
}
2009-01-08 21:50:21 +00:00
function FinishTestItem ( )
{
2017-06-16 19:08:45 +00:00
logger . testEnd ( gURLs [ 0 ] . identifier , "OK" ) ;
2009-02-10 22:05:27 +00:00
// Replace document with BLANK_URL_FOR_CLEARING in case there are
2009-01-08 21:50:21 +00:00
// assertions when unloading.
2016-02-05 20:44:20 +00:00
logger . debug ( "Loading a blank page" ) ;
2011-02-03 19:54:10 +00:00
// After clearing, content will notify us of the assertion count
// and tests will continue.
SendClear ( ) ;
2013-06-07 05:10:31 +00:00
gFailedNoPaint = false ;
2015-03-11 18:51:59 +00:00
gFailedOpaqueLayer = false ;
gFailedOpaqueLayerMessages = [ ] ;
gFailedAssignedLayer = false ;
gFailedAssignedLayerMessages = [ ] ;
2009-01-08 21:50:21 +00:00
}
2011-02-03 19:54:10 +00:00
function DoAssertionCheck ( numAsserts )
2009-01-08 21:50:21 +00:00
{
2009-01-13 19:50:40 +00:00
if ( gDebug . isDebugBuild ) {
2011-02-03 19:54:10 +00:00
if ( gBrowserIsRemote ) {
// Count chrome-process asserts too when content is out of
// process.
var newAssertionCount = gDebug . assertionCount ;
var numLocalAsserts = newAssertionCount - gAssertionCount ;
gAssertionCount = newAssertionCount ;
numAsserts += numLocalAsserts ;
}
2009-01-13 19:50:40 +00:00
var minAsserts = gURLs [ 0 ] . minAsserts ;
var maxAsserts = gURLs [ 0 ] . maxAsserts ;
2017-06-16 19:08:45 +00:00
logger . assertionCount ( gURLs [ 0 ] . identifier , numAsserts , minAsserts , maxAsserts ) ;
2009-01-08 21:50:21 +00:00
}
2015-06-04 17:44:55 +00:00
if ( gURLs [ 0 ] . chaosMode ) {
gWindowUtils . leaveChaosMode ( ) ;
}
2013-05-30 20:14:46 +00:00
2009-01-08 21:50:21 +00:00
// And start the next test.
2007-02-13 00:54:02 +00:00
gURLs . shift ( ) ;
StartCurrentTest ( ) ;
}
2011-02-03 19:54:10 +00:00
2011-02-23 17:45:09 +00:00
function ResetRenderingState ( )
{
SendResetRenderingState ( ) ;
// We would want to clear any viewconfig here, if we add support for it
}
2011-02-03 19:54:10 +00:00
2011-12-29 00:24:48 +00:00
function RestoreChangedPreferences ( )
{
if ( gPrefsToRestore . length > 0 ) {
var prefs = Components . classes [ "@mozilla.org/preferences-service;1" ] .
2012-01-17 02:01:25 +00:00
getService ( Components . interfaces . nsIPrefBranch ) ;
2012-11-27 23:06:33 +00:00
gPrefsToRestore . reverse ( ) ;
2011-12-29 00:24:48 +00:00
gPrefsToRestore . forEach ( function ( ps ) {
var value = ps . value ;
if ( ps . type == PREF _BOOLEAN ) {
prefs . setBoolPref ( ps . name , value ) ;
} else if ( ps . type == PREF _STRING ) {
prefs . setCharPref ( ps . name , value ) ;
value = '"' + value + '"' ;
} else if ( ps . type == PREF _INTEGER ) {
prefs . setIntPref ( ps . name , value ) ;
}
2016-02-05 20:44:20 +00:00
logger . info ( "RESTORE PREFERENCE pref(" + ps . name + "," + value + ")" ) ;
2011-12-29 00:24:48 +00:00
} ) ;
gPrefsToRestore = [ ] ;
}
}
2011-02-03 19:54:10 +00:00
function RegisterMessageListenersAndLoadContentScript ( )
{
gBrowserMessageManager . addMessageListener (
"reftest:AssertionCount" ,
function ( m ) { RecvAssertionCount ( m . json . count ) ; }
) ;
gBrowserMessageManager . addMessageListener (
"reftest:ContentReady" ,
2016-10-28 01:52:51 +00:00
function ( m ) { return RecvContentReady ( m . data ) ; }
2011-02-03 19:54:10 +00:00
) ;
gBrowserMessageManager . addMessageListener (
"reftest:Exception" ,
function ( m ) { RecvException ( m . json . what ) }
) ;
gBrowserMessageManager . addMessageListener (
"reftest:FailedLoad" ,
function ( m ) { RecvFailedLoad ( m . json . why ) ; }
) ;
2013-06-07 05:10:31 +00:00
gBrowserMessageManager . addMessageListener (
"reftest:FailedNoPaint" ,
function ( m ) { RecvFailedNoPaint ( ) ; }
) ;
2015-03-11 18:51:59 +00:00
gBrowserMessageManager . addMessageListener (
"reftest:FailedOpaqueLayer" ,
function ( m ) { RecvFailedOpaqueLayer ( m . json . why ) ; }
) ;
gBrowserMessageManager . addMessageListener (
"reftest:FailedAssignedLayer" ,
function ( m ) { RecvFailedAssignedLayer ( m . json . why ) ; }
) ;
2011-02-03 19:54:10 +00:00
gBrowserMessageManager . addMessageListener (
"reftest:InitCanvasWithSnapshot" ,
function ( m ) { return RecvInitCanvasWithSnapshot ( ) ; }
) ;
gBrowserMessageManager . addMessageListener (
"reftest:Log" ,
function ( m ) { RecvLog ( m . json . type , m . json . msg ) ; }
) ;
gBrowserMessageManager . addMessageListener (
"reftest:ScriptResults" ,
function ( m ) { RecvScriptResults ( m . json . runtimeMs , m . json . error , m . json . results ) ; }
) ;
2017-09-06 16:54:29 +00:00
gBrowserMessageManager . addMessageListener (
"reftest:PrintResult" ,
function ( m ) { RecvPrintResult ( m . json . runtimeMs , m . json . status , m . json . fileName ) ; }
) ;
2011-02-03 19:54:10 +00:00
gBrowserMessageManager . addMessageListener (
"reftest:TestDone" ,
function ( m ) { RecvTestDone ( m . json . runtimeMs ) ; }
) ;
gBrowserMessageManager . addMessageListener (
"reftest:UpdateCanvasForInvalidation" ,
function ( m ) { RecvUpdateCanvasForInvalidation ( m . json . rects ) ; }
) ;
2013-06-18 07:59:46 +00:00
gBrowserMessageManager . addMessageListener (
"reftest:UpdateWholeCanvasForInvalidation" ,
function ( m ) { RecvUpdateWholeCanvasForInvalidation ( ) ; }
) ;
2011-04-26 03:02:38 +00:00
gBrowserMessageManager . addMessageListener (
"reftest:ExpectProcessCrash" ,
function ( m ) { RecvExpectProcessCrash ( ) ; }
) ;
2011-02-03 19:54:10 +00:00
2013-11-24 05:32:45 +00:00
gBrowserMessageManager . loadFrameScript ( "chrome://reftest/content/reftest-content.js" , true , true ) ;
2011-02-03 19:54:10 +00:00
}
function RecvAssertionCount ( count )
{
DoAssertionCheck ( count ) ;
}
2016-10-28 01:52:51 +00:00
function RecvContentReady ( info )
2011-02-03 19:54:10 +00:00
{
2016-10-28 01:52:51 +00:00
gContentGfxInfo = info . gfx ;
2011-02-03 19:54:10 +00:00
InitAndStartRefTests ( ) ;
return { remote : gBrowserIsRemote } ;
}
function RecvException ( what )
{
2016-02-05 20:44:20 +00:00
logger . error ( gCurrentURL + " | " + what ) ;
2011-02-03 19:54:10 +00:00
++ gTestResults . Exception ;
}
function RecvFailedLoad ( why )
{
LoadFailed ( why ) ;
}
2013-06-07 05:10:31 +00:00
function RecvFailedNoPaint ( )
{
gFailedNoPaint = true ;
}
2015-03-11 18:51:59 +00:00
function RecvFailedOpaqueLayer ( why ) {
gFailedOpaqueLayer = true ;
gFailedOpaqueLayerMessages . push ( why ) ;
}
function RecvFailedAssignedLayer ( why ) {
gFailedAssignedLayer = true ;
gFailedAssignedLayerMessages . push ( why ) ;
}
2011-02-03 19:54:10 +00:00
function RecvInitCanvasWithSnapshot ( )
{
var painted = InitCurrentCanvasWithSnapshot ( ) ;
return { painted : painted } ;
}
function RecvLog ( type , msg )
{
2016-02-05 20:44:20 +00:00
msg = "[CONTENT] " + msg ;
2011-02-03 19:54:10 +00:00
if ( type == "info" ) {
2016-02-05 20:44:20 +00:00
TestBuffer ( msg ) ;
2011-02-03 19:54:10 +00:00
} else if ( type == "warning" ) {
2016-02-05 20:44:20 +00:00
logger . warning ( msg ) ;
2011-02-03 19:54:10 +00:00
} else {
2016-02-05 20:44:20 +00:00
logger . error ( "REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | unknown log type " + type + "\n" ) ;
2011-02-03 19:54:10 +00:00
++ gTestResults . Exception ;
}
}
function RecvScriptResults ( runtimeMs , error , results )
{
RecordResult ( runtimeMs , error , results ) ;
}
2017-09-06 16:54:29 +00:00
function RecvPrintResult ( runtimeMs , status , fileName )
{
if ( ! Components . isSuccessCode ( status ) ) {
logger . error ( "REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | error during printing\n" ) ;
++ gTestResults . Exception ;
}
RecordResult ( runtimeMs , '' , fileName ) ;
}
2011-02-03 19:54:10 +00:00
function RecvTestDone ( runtimeMs )
{
RecordResult ( runtimeMs , '' , [ ] ) ;
}
function RecvUpdateCanvasForInvalidation ( rects )
{
UpdateCurrentCanvasForInvalidation ( rects ) ;
}
2013-06-18 07:59:46 +00:00
function RecvUpdateWholeCanvasForInvalidation ( )
{
UpdateWholeCurrentCanvasForInvalidation ( ) ;
}
2011-04-26 03:02:38 +00:00
function OnProcessCrashed ( subject , topic , data )
{
var id ;
subject = subject . QueryInterface ( CI . nsIPropertyBag2 ) ;
if ( topic == "plugin-crashed" ) {
id = subject . getPropertyAsAString ( "pluginDumpID" ) ;
} else if ( topic == "ipc:content-shutdown" ) {
id = subject . getPropertyAsAString ( "dumpID" ) ;
}
if ( id ) {
gExpectedCrashDumpFiles . push ( id + ".dmp" ) ;
gExpectedCrashDumpFiles . push ( id + ".extra" ) ;
}
}
function RegisterProcessCrashObservers ( )
{
var os = CC [ NS _OBSERVER _SERVICE _CONTRACTID ]
. getService ( CI . nsIObserverService ) ;
2017-04-14 19:51:38 +00:00
os . addObserver ( OnProcessCrashed , "plugin-crashed" ) ;
os . addObserver ( OnProcessCrashed , "ipc:content-shutdown" ) ;
2011-04-26 03:02:38 +00:00
}
function RecvExpectProcessCrash ( )
{
gExpectingProcessCrash = true ;
}
2011-02-03 19:54:10 +00:00
function SendClear ( )
{
gBrowserMessageManager . sendAsyncMessage ( "reftest:Clear" ) ;
}
function SendLoadScriptTest ( uri , timeout )
{
gBrowserMessageManager . sendAsyncMessage ( "reftest:LoadScriptTest" ,
{ uri : uri , timeout : timeout } ) ;
}
2017-09-06 16:54:29 +00:00
function SendLoadPrintTest ( uri , timeout )
{
gBrowserMessageManager . sendAsyncMessage ( "reftest:LoadPrintTest" ,
{ uri : uri , timeout : timeout } ) ;
}
2011-02-03 19:54:10 +00:00
function SendLoadTest ( type , uri , timeout )
{
gBrowserMessageManager . sendAsyncMessage ( "reftest:LoadTest" ,
{ type : type , uri : uri , timeout : timeout }
) ;
}
2011-02-23 17:45:09 +00:00
function SendResetRenderingState ( )
2011-02-03 19:54:10 +00:00
{
2011-02-23 17:45:09 +00:00
gBrowserMessageManager . sendAsyncMessage ( "reftest:ResetRenderingState" ) ;
2011-02-03 19:54:10 +00:00
}
2017-09-06 16:54:29 +00:00
function readPdf ( path , callback ) {
OS . File . open ( path , { read : true } ) . then ( function ( file ) {
file . flush ( ) . then ( function ( ) {
file . read ( ) . then ( function ( data ) {
var fakePort = new PDFJS . main . LoopbackPort ( true ) ;
PDFJS . worker . WorkerMessageHandler . initializeFromPort ( fakePort ) ;
var myWorker = new PDFJS . main . PDFWorker ( "worker" , fakePort ) ;
PDFJS . main . PDFJS . getDocument ( {
worker : myWorker ,
data : data
} ) . then ( function ( pdf ) {
callback ( null , pdf ) ;
} , function ( ) {
callback ( new Error ( "Couldn't parse " + path ) ) ;
} ) ;
return ;
} , function ( ) {
callback ( new Error ( "Couldn't read PDF" ) ) ;
} ) ;
} ) ;
} ) ;
}
function comparePdfs ( pathToTestPdf , pathToRefPdf , callback ) {
Promise . all ( [ pathToTestPdf , pathToRefPdf ] . map ( function ( path ) {
return new Promise ( function ( resolve , reject ) {
readPdf ( path , function ( error , pdf ) {
// Resolve or reject outer promise. reject and resolve are
// passed to the callback function given as first arguments
// to the Promise constructor.
if ( error ) {
reject ( error ) ;
} else {
resolve ( pdf ) ;
}
} ) ;
} ) ;
} ) ) . then ( function ( pdfs ) {
var numberOfPages = pdfs [ 1 ] . numPages ;
var sameNumberOfPages = numberOfPages === pdfs [ 0 ] . numPages ;
var resultPromises = [ Promise . resolve ( {
passed : sameNumberOfPages ,
description : "Expected number of pages: " + numberOfPages +
", got " + pdfs [ 0 ] . numPages
} ) ] ;
if ( sameNumberOfPages ) {
for ( var i = 0 ; i < numberOfPages ; i ++ ) {
var pageNum = i + 1 ;
var testPagePromise = pdfs [ 0 ] . getPage ( pageNum ) ;
var refPagePromise = pdfs [ 1 ] . getPage ( pageNum ) ;
resultPromises . push ( new Promise ( function ( resolve , reject ) {
Promise . all ( [ testPagePromise , refPagePromise ] ) . then ( function ( pages ) {
var testTextPromise = pages [ 0 ] . getTextContent ( ) ;
var refTextPromise = pages [ 1 ] . getTextContent ( ) ;
Promise . all ( [ testTextPromise , refTextPromise ] ) . then ( function ( texts ) {
var testTextItems = texts [ 0 ] . items ;
var refTextItems = texts [ 1 ] . items ;
var testText ;
var refText ;
var passed = refTextItems . every ( function ( o , i ) {
refText = o . str ;
if ( ! testTextItems [ i ] ) {
return false ;
}
testText = testTextItems [ i ] . str ;
return testText === refText ;
} ) ;
var description ;
if ( passed ) {
if ( testTextItems . length > refTextItems . length ) {
passed = false ;
description = "Page " + pages [ 0 ] . pageNumber +
" contains unexpected text like '" +
testTextItems [ refTextItems . length ] . str + "'" ;
} else {
description = "Page " + pages [ 0 ] . pageNumber +
" contains same text"
}
} else {
description = "Expected page " + pages [ 0 ] . pageNumber +
" to contain text '" + refText ;
if ( testText ) {
description += "' but found '" + testText +
"' instead" ;
}
}
resolve ( {
passed : passed ,
description : description
} ) ;
} , reject ) ;
} , reject ) ;
} ) ) ;
}
}
Promise . all ( resultPromises ) . then ( function ( results ) {
callback ( null , results ) ;
} ) ;
} , function ( error ) {
callback ( error ) ;
} ) ;
}