author | Chris Jones <jones.chris.g@gmail.com> |
Thu, 03 Feb 2011 13:54:10 -0600 | |
changeset 61873 | c1523d3f78410892b1750d98e414171ca4793fe3 |
parent 61865 | 9c815db836e360e9ca4fa4c6f54f31852e13f004 |
child 61875 | 41258e566f2e5ccb14cee2c645635d9f811cc522 |
push id | unknown |
push user | unknown |
push date | unknown |
reviewers | dbaron, roc, ted, a |
bugs | 615386 |
milestone | 2.0b12pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/html/content/reftests/autofocus/reftest.list +++ b/content/html/content/reftests/autofocus/reftest.list @@ -1,11 +1,11 @@ -== input-load.html input-ref.html -== input-create.html input-ref.html -== button-load.html button-ref.html -== button-create.html button-ref.html -== textarea-load.html textarea-ref.html -== textarea-create.html textarea-ref.html -== select-load.html select-ref.html -== select-create.html select-ref.html -== autofocus-after-load.html autofocus-after-load-ref.html -== autofocus-leaves-iframe.html autofocus-leaves-iframe-ref.html -== autofocus-after-body-focus.html autofocus-after-body-focus-ref.html +needs-focus == input-load.html input-ref.html +needs-focus == input-create.html input-ref.html +needs-focus == button-load.html button-ref.html +needs-focus == button-create.html button-ref.html +needs-focus == textarea-load.html textarea-ref.html +needs-focus == textarea-create.html textarea-ref.html +needs-focus == select-load.html select-ref.html +needs-focus == select-create.html select-ref.html +needs-focus == autofocus-after-load.html autofocus-after-load-ref.html +needs-focus == autofocus-leaves-iframe.html autofocus-leaves-iframe-ref.html +needs-focus == autofocus-after-body-focus.html autofocus-after-body-focus-ref.html
--- a/editor/libeditor/html/crashtests/crashtests.list +++ b/editor/libeditor/html/crashtests/crashtests.list @@ -6,17 +6,17 @@ load 418923-1.html load 420439.html load 428489-1.html load 431086-1.xhtml load 448329-1.html load 448329-2.html load 448329-3.html load 456727-1.html load 456727-2.html -asserts(2) load 467647-1.html # bug 382210, bug 414178 +needs-focus asserts(2) load 467647-1.html # bug 382210, bug 414178 load 499844-1.html load 503709-1.xhtml load 513375-1.xhtml load 535632-1.xhtml load 574558-1.xhtml load 582138-1.xhtml load 612565-1.html load 615015-1.html
--- a/editor/txmgr/tests/crashtests/crashtests.list +++ b/editor/txmgr/tests/crashtests/crashtests.list @@ -1,2 +1,2 @@ -asserts(3) load 407072-1.html # bug 382210? +needs-focus asserts(3) load 407072-1.html # bug 382210? load 449006-1.html
--- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -88,27 +88,27 @@ load 336291-1.html load 336999-1.xul load 337066-1.xhtml load 337268-1.html load 337419-1.html load 337476-1.xul load 338703-1.html load 339651-1.html load 340093-1.xul -load 341858-1.html +asserts-if(browserIsRemote,1) load 341858-1.html # bug 622188 load 342145-1.xhtml load 343293-1.xhtml load 343293-2.xhtml load 343540-1.html load 344057-1.xhtml load 344064-1.html load 344300-1.html load 344300-2.html load 344340-1.xul -load 347898-1.html +asserts-if(browserIsRemote,1) load 347898-1.html # bug 622188 load 348126-1.html load 348688-1.html load 348708-1.xhtml asserts(2) load 348729-1.html # bug 548836 load 349095-1.xhtml load 350128-1.xhtml load 350267-1.html load 354133-1.html
--- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -30,17 +30,17 @@ load 334602-1.html load 337412-1.html load 337883-1.html load 337883-2.html load 339769-1.html load 342322-1.html load 343206-1.xhtml load 345139-1.xhtml load 345617-1.html -load 348887-1.html +skip load 348887-1.html # bug 623091 load 348991-1.xhtml load 354458-1.html load 354458-2.html load 355426-1.html load 359371-1.html load 359371-2.html load 363722-1.html load 363722-2.html
--- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -142,17 +142,17 @@ random == 99850-1b.html 99850-1-ref.html == 179596-1b.html 179596-1b-ref.html == 179596-2.html 179596-2-ref.html == 179596-2.html 179596-2-ref2.html == 179596-2.html 179596-2-ref3.html == 180085-1.html 180085-1-ref.html == 180085-2.html 180085-2-ref.html == 185388-1.html 185388-1-ref.html == 192902-1.html 192902-ref.html -!= 200774-1.html about:blank # really a crashtest +!= 200774-1.html about:blank == 201215-1.html 201215-1-ref.html == 201293-1a.html 201293-1-ref.html == 201293-1b.html 201293-1-ref.html == 201293-1c.html 201293-1-ref.html == 201293-1d.html 201293-1-ref.html == 203727.html 203727-ref.html == 206516-1.html 206516-1-ref.html == 206631-1.html 206631-1-ref.html @@ -1350,17 +1350,17 @@ random-if(cocoaWidget&&layersGPUAccelera == 502942-1.html 502942-1-ref.html == 502447-1.html 502447-1-ref.html == 502795-1.html 502795-1-ref.html == 503364-1a.html 503364-1-ref.html == 503364-1b.html 503364-1-ref.html == 503399.html 503399-ref.html # Reftest for bug 503531 marked as failing; should be re-enabled when # bug 607548 gets resolved. -fails == 503531-1.html 503531-1-ref.html +needs-focus fails == 503531-1.html 503531-1-ref.html == 504032-1.html 504032-1-ref.html == 505743-1.html about:blank == 506481-1.html 506481-1-ref.html == 507187-1.html 507187-1-ref.html == 507487-1.html 507487-1-ref.html == 507487-2.xhtml 507487-2-ref.xhtml == 507762-1.html 507762-1-ref.html == 507762-2.html 507762-2-ref.html @@ -1423,19 +1423,19 @@ asserts(5) == 528038-2.html 528038-2-ref == 539323-1.html 539323-1-ref.html == 539323-2.html 539323-2-ref.html == 539323-3.html 539323-3-ref.html == 539880-1.html 539880-1-ref.html == 539880-1-dynamic.html 539880-1-ref.html == 539949-1.html#test2 539949-1-ref.html#test2 == 541382-1.html 541382-1-ref.html random-if(!haveTestPlugin) == 541406-1.html 541406-1-ref.html -!= 542116-1.html 542116-1-ref.html -asserts(1) != 542116-2.html 542116-2-ref.html # bug 596901 -!= 542116-3.html 542116-3-ref.html +needs-focus != 542116-1.html 542116-1-ref.html +needs-focus asserts(1) != 542116-2.html 542116-2-ref.html # bug 596901 +needs-focus != 542116-3.html 542116-3-ref.html == 542317-1.html 542317-1-ref.html == 542605-hidden-unscrollable.xul 542605-hidden-unscrollable-ref.xul == 542620-1.html 542620-1-ref.html == 545049-1.html 545049-1-ref.html == 546033-1.html 546033-1-ref.html random-if(!haveTestPlugin) == 546071-1.html 546071-1-ref.html == 549184-1.html 549184-1-ref.html == 550325-1.html 550325-1-ref.html @@ -1483,17 +1483,17 @@ random-if(d2d) == 555388-1.html 555388-1 == 563584-9d.html 563584-9cd-ref.html == 563584-10a.html 563584-10-ref.html == 563584-10b.html 563584-10-ref.html == 563584-11.html 563584-11-ref.html == 564054-1.html 564054-1-ref.html random-if(layersGPUAccelerated) == 564991-1.html 564991-1-ref.html == 565819-1.html 565819-ref.html == 565819-2.html 565819-ref.html -== 568441.html 568441-ref.html +needs-focus == 568441.html 568441-ref.html == 569006-1.html 569006-1-ref.html == 571281-1a.html 571281-1-ref.html == 571281-1b.html 571281-1-ref.html == 571281-1c.html 571281-1-ref.html == 571347-1a.html 571347-1-ref.html == 571347-1b.html 571347-1-ref.html == 571347-2a.html 571347-2-ref.html == 571347-2b.html 571347-2-ref.html @@ -1548,25 +1548,25 @@ fails-if(!haveTestPlugin) == 599476.html == 602200-2.html 602200-2-ref.html == 602200-3.html 602200-3-ref.html == 602200-4.html 602200-4-ref.html == 604737.html 604737-ref.html == 605138-1.html 605138-1-ref.html == 605157-1.xhtml 605157-1-ref.xhtml == 609272-1.html 609272-1-ref.html == 608636-1.html 608636-1-ref.html -== 613433-1.html 613433-1-ref.html -== 613433-1.html 613433-2-ref.html -== 613433-1.html 613433-3-ref.html -== 613433-2.html 613433-1-ref.html -== 613433-2.html 613433-2-ref.html -== 613433-2.html 613433-3-ref.html -== 613433-3.html 613433-1-ref.html -== 613433-3.html 613433-2-ref.html -== 613433-3.html 613433-3-ref.html +needs-focus == 613433-1.html 613433-1-ref.html +needs-focus == 613433-1.html 613433-2-ref.html +needs-focus == 613433-1.html 613433-3-ref.html +needs-focus == 613433-2.html 613433-1-ref.html +needs-focus == 613433-2.html 613433-2-ref.html +needs-focus == 613433-2.html 613433-3-ref.html +needs-focus == 613433-3.html 613433-1-ref.html +needs-focus == 613433-3.html 613433-2-ref.html +needs-focus == 613433-3.html 613433-3-ref.html == 614272-1.svg 614272-1-ref.svg HTTP(..) == 615121-1.html 615121-1-ref.html HTTP(..) != 615121-2.html 615121-2-notref.html == 617242-1.html 617242-1-ref.html != 618071.html 618071-notref.html == 619117-1.html 619117-1-ref.html HTTP(..) == 621253-1-externalFilter.html 621253-1-ref.html # XXX update reference case after bug 541270 is fixed == 621253-1-internalFilter.html 621253-1-ref.html # XXX update reference case after bug 541270 is fixed
--- a/layout/reftests/css-placeholder/input/reftest.list +++ b/layout/reftests/css-placeholder/input/reftest.list @@ -1,11 +1,11 @@ == placeholder-simple.html placeholder-simple-ref.html -== placeholder-focus.html placeholder-focus-ref.html -== placeholder-blur.html placeholder-simple-ref.html +needs-focus == placeholder-focus.html placeholder-focus-ref.html +needs-focus == placeholder-blur.html placeholder-simple-ref.html == placeholder-value.html placeholder-value-ref.html == placeholder-empty-string.html placeholder-empty-string-ref.html == placeholder-complex.html placeholder-complex-ref.html == placeholder-add.html placeholder-simple-ref.html == placeholder-removal.html input-ref.html == placeholder-value-set.html placeholder-value-ref.html == placeholder-value-unset.html placeholder-simple-ref.html == placeholder-value-reset.html placeholder-simple-ref.html
--- a/layout/reftests/css-placeholder/textarea/reftest.list +++ b/layout/reftests/css-placeholder/textarea/reftest.list @@ -1,11 +1,11 @@ == placeholder-simple.html placeholder-simple-ref.html -== placeholder-focus.html placeholder-focus-ref.html -== placeholder-blur.html placeholder-simple-ref.html +needs-focus == placeholder-focus.html placeholder-focus-ref.html +needs-focus == placeholder-blur.html placeholder-simple-ref.html == placeholder-value.html placeholder-value-ref.html == placeholder-empty-string.html placeholder-empty-string-ref.html == placeholder-complex.html placeholder-complex-ref.html == placeholder-add.html placeholder-simple-ref.html == placeholder-removal.html textarea-ref.html == placeholder-value-set.html placeholder-value-ref.html == placeholder-value-unset.html placeholder-simple-ref.html == placeholder-value-reset.html placeholder-simple-ref.html
--- a/layout/reftests/css-ui-invalid/default-style/reftest.list +++ b/layout/reftests/css-ui-invalid/default-style/reftest.list @@ -1,11 +1,11 @@ == input.html input-ref.html == button.html button-ref.html == textarea.html textarea-ref.html == select.html select-ref.html == fieldset.html fieldset-ref.html == output.html output-ref.html -== input-focus.html input-focus-ref.html -== button-focus.html button-focus-ref.html -== textarea-focus.html textarea-focus-ref.html -== select-focus.html select-focus-ref.html -== textarea-focus.html textarea-focus-ref.html +needs-focus == input-focus.html input-focus-ref.html +needs-focus == button-focus.html button-focus-ref.html +needs-focus == textarea-focus.html textarea-focus-ref.html +needs-focus == select-focus.html select-focus-ref.html +
--- a/layout/reftests/editor/reftest.list +++ b/layout/reftests/editor/reftest.list @@ -8,17 +8,17 @@ include xul/reftest.list == dynamic-1.html dynamic-ref.html == dynamic-type-1.html dynamic-ref.html == dynamic-type-2.html dynamic-ref.html == dynamic-type-3.html dynamic-ref.html == dynamic-type-4.html dynamic-ref.html == passwd-1.html passwd-ref.html != passwd-2.html passwd-ref.html == passwd-3.html passwd-ref.html -asserts(1) == passwd-4.html passwd-ref.html # bug 596901 +needs-focus asserts(1) == passwd-4.html passwd-ref.html # bug 596901 == emptypasswd-1.html emptypasswd-ref.html == emptypasswd-2.html emptypasswd-ref.html == caret_on_positioned.html caret_on_positioned-ref.html != spellcheck-input-disabled.html spellcheck-input-ref.html == spellcheck-input-attr-before.html spellcheck-input-ref.html == spellcheck-input-attr-after.html spellcheck-input-ref.html == spellcheck-input-attr-inherit.html spellcheck-input-ref.html == spellcheck-input-attr-dynamic.html spellcheck-input-ref.html @@ -36,14 +36,14 @@ asserts(1) == passwd-4.html passwd-ref.h != spellcheck-textarea-attr-dynamic-inherit.html spellcheck-textarea-ref.html != spellcheck-textarea-property-dynamic.html spellcheck-textarea-ref.html != spellcheck-textarea-property-dynamic-inherit.html spellcheck-textarea-ref.html != spellcheck-textarea-attr-dynamic-override.html spellcheck-textarea-ref.html != spellcheck-textarea-attr-dynamic-override-inherit.html spellcheck-textarea-ref.html != spellcheck-textarea-property-dynamic-override.html spellcheck-textarea-ref.html != spellcheck-textarea-property-dynamic-override-inherit.html spellcheck-textarea-ref.html == caret_on_focus.html caret_on_focus-ref.html -!= caret_on_textarea_lastline.html caret_on_textarea_lastline-ref.html -== input-text-onfocus-reframe.html input-text-onfocus-reframe-ref.html -== input-text-notheme-onfocus-reframe.html input-text-notheme-onfocus-reframe-ref.html -== caret_after_reframe.html caret_after_reframe-ref.html +needs-focus != caret_on_textarea_lastline.html caret_on_textarea_lastline-ref.html +needs-focus == input-text-onfocus-reframe.html input-text-onfocus-reframe-ref.html +needs-focus == input-text-notheme-onfocus-reframe.html input-text-notheme-onfocus-reframe-ref.html +needs-focus == caret_after_reframe.html caret_after_reframe-ref.html == nobogusnode-1.html nobogusnode-ref.html == nobogusnode-2.html nobogusnode-ref.html
--- a/layout/reftests/forms/placeholder/reftest.list +++ b/layout/reftests/forms/placeholder/reftest.list @@ -3,24 +3,24 @@ == placeholder-1-textarea.html placeholder-visible-textarea-ref.html == placeholder-2.html placeholder-visible-ref.html == placeholder-2-textarea.html placeholder-visible-textarea-ref.html == placeholder-3.html placeholder-overridden-ref.html == placeholder-4.html placeholder-overridden-ref.html == placeholder-5.html placeholder-visible-ref.html == placeholder-6.html placeholder-overflow-ref.html == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html -== placeholder-7.html placeholder-focus-ref.html -== placeholder-8.html placeholder-focus-ref.html -== placeholder-9.html placeholder-focus-ref.html -== placeholder-10.html placeholder-visible-ref.html +needs-focus == placeholder-7.html placeholder-focus-ref.html +needs-focus == placeholder-8.html placeholder-focus-ref.html +needs-focus == placeholder-9.html placeholder-focus-ref.html +needs-focus == placeholder-10.html placeholder-visible-ref.html == placeholder-11.html placeholder-visible-ref.html == placeholder-12.html placeholder-visible-ref.html == placeholder-13.html placeholder-visible-ref.html == placeholder-14.html placeholder-visible-ref.html -== placeholder-15.html placeholder-focus-ref.html -== placeholder-16.html placeholder-focus-ref.html -== placeholder-17.html placeholder-focus-ref.html +needs-focus == placeholder-15.html placeholder-focus-ref.html +needs-focus == placeholder-16.html placeholder-focus-ref.html +needs-focus == placeholder-17.html placeholder-focus-ref.html == placeholder-18.html placeholder-overridden-ref.html == placeholder-19.xul placeholder-overridden-ref.xul -== placeholder-20.html placeholder-focus-ref.html -== placeholder-21.html placeholder-focus-ref.html -== placeholder-22.html placeholder-focus-ref.html +needs-focus == placeholder-20.html placeholder-focus-ref.html +needs-focus == placeholder-21.html placeholder-focus-ref.html +needs-focus == placeholder-22.html placeholder-focus-ref.html
new file mode 100644 --- /dev/null +++ b/layout/reftests/reftest-sanity/needs-focus.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <script type="text/javascript"> +function focusInput() { + document.getElementById('i').focus(); +} +function done() { + document.documentElement.className = ''; +} + </script> + <body onload="focusInput();"> + <input type="text" id="i" onfocus="done();"> + </body> +</html>
--- a/layout/reftests/reftest-sanity/reftest.list +++ b/layout/reftests/reftest-sanity/reftest.list @@ -73,8 +73,11 @@ include urlprefixtests.list # Test that the harness gives the correct page dimensions. != page-width-3.9in.html page-width-4in.html == page-width-4.1in.html page-width-4in.html == page-width-auto.html page-width-4in.html != page-height-2in.html page-height-2.1in.html == page-height-2in.html page-height-nobreak.html == page-height-2.1in.html page-height-forcebreak.html + +# Check that tests that need focus are skipped when it's not available +needs-focus load needs-focus.html
--- a/layout/tools/reftest/README.txt +++ b/layout/tools/reftest/README.txt @@ -53,16 +53,19 @@ 2. A test item fails The test passes if the images of the two renderings DO NOT meet the conditions specified in the <type>. fails-if(condition) If the condition is met, the test passes if the images of the two renderings DO NOT meet the conditions of <type>. If the condition is not met, the test passes if the conditions of <type> are met. + needs-focus The test fails or times out if the reftest window is not + focused. + random The results of the test are random and therefore not to be considered in the output. random-if(condition) The results of the test are random if a given condition is met. silentfail This test may fail silently, and if that happens it should count as if the test passed. This is useful for cases where
--- a/layout/tools/reftest/jar.mn +++ b/layout/tools/reftest/jar.mn @@ -1,11 +1,12 @@ reftest.jar: % content reftest %content/ * content/quit.js (quit.js) * content/reftest.js (reftest.js) + content/reftest-content.js (reftest-content.js) content/reftest.xul (reftest.xul) content/MozillaFileLogger.js (../../../testing/mochitest/tests/SimpleTest/MozillaFileLogger.js) #ifdef XPI_NAME % component {32530271-8c1b-4b7d-a812-218e42c6bb23} components/reftest-cmdline.js % contract @mozilla.org/commandlinehandler/general-startup;1?type=reftest {32530271-8c1b-4b7d-a812-218e42c6bb23} % category command-line-handler m-reftest @mozilla.org/commandlinehandler/general-startup;1?type=reftest #endif
--- a/layout/tools/reftest/print-manifest-dirs.py +++ b/layout/tools/reftest/print-manifest-dirs.py @@ -34,17 +34,17 @@ # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** import sys, os.path, re commentRE = re.compile(r"\s+#") -conditionsRE = re.compile(r"^(fails|random|skip|asserts)") +conditionsRE = re.compile(r"^(fails|needs-focus|random|skip|asserts)") httpRE = re.compile(r"HTTP\((\.\.(\/\.\.)*)\)") protocolRE = re.compile(r"^\w+:") def parseManifest(manifest, dirs): """Parse the reftest manifest |manifest|, adding all directories containing tests (and the dirs containing the manifests themselves) to the set |dirs|.""" manifestdir = os.path.dirname(os.path.abspath(manifest)) dirs.add(manifestdir)
copy from layout/tools/reftest/reftest.js copy to layout/tools/reftest/reftest-content.js --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest-content.js @@ -35,167 +35,94 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ const CC = Components.classes; const CI = Components.interfaces; const CR = Components.results; +/** + * FIXME/bug 622224: work around lack of reliable setTimeout available + * to frame scripts. + */ +// This gives us >=2^30 unique timer IDs, enough for 1 per ms for 12.4 +// days. Should be fine as a temporary workaround. +var gNextTimeoutId = 0; +var gTimeoutTable = { }; // int -> nsITimer + +function setTimeout(callbackFn, delayMs) { + var id = gNextTimeoutId++; + var timer = CC["@mozilla.org/timer;1"].createInstance(CI.nsITimer); + timer.initWithCallback({ + notify: function notify_callback() { + clearTimeout(id); + callbackFn(); + } + }, + delayMs, + timer.TYPE_ONE_SHOT); + + gTimeoutTable[id] = timer; + + return id; +} + +function clearTimeout(id) { + var timer = gTimeoutTable[id]; + if (timer) { + timer.cancel(); + delete gTimeoutTable[id]; + } +} + const XHTML_NS = "http://www.w3.org/1999/xhtml"; -const NS_LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1"; -const NS_GFXINFO_CONTRACTID = "@mozilla.org/gfx/info;1"; -const IO_SERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; const DEBUG_CONTRACTID = "@mozilla.org/xpcom/debug;1"; -const NS_LOCALFILEINPUTSTREAM_CONTRACTID = - "@mozilla.org/network/file-input-stream;1"; -const NS_SCRIPTSECURITYMANAGER_CONTRACTID = - "@mozilla.org/scriptsecuritymanager;1"; -const NS_REFTESTHELPER_CONTRACTID = - "@mozilla.org/reftest-helper;1"; -const NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX = - "@mozilla.org/network/protocol;1?name="; -const NS_XREAPPINFO_CONTRACTID = - "@mozilla.org/xre/app-info;1"; - -var gLoadTimeout = 0; -var gTimeoutHook = null; -var gRemote = false; -var gTotalChunks = 0; -var gThisChunk = 0; +const PRINTSETTINGS_CONTRACTID = "@mozilla.org/gfx/printsettings-service;1"; // "<!--CLEAR-->" const BLANK_URL_FOR_CLEARING = "data:text/html,%3C%21%2D%2DCLEAR%2D%2D%3E"; -var gBrowser; -var gCanvas1, gCanvas2; -// gCurrentCanvas is non-null between InitCurrentCanvasWithSnapshot and the next -// RecordResult. -var gCurrentCanvas = null; -var gURLs; -// 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; -var gTestResults = { - // Successful... - Pass: 0, - LoadOnly: 0, - // Unexpected... - Exception: 0, - FailedLoad: 0, - UnexpectedFail: 0, - UnexpectedPass: 0, - AssertionUnexpected: 0, - AssertionUnexpectedFixed: 0, - // Known problems... - KnownFail : 0, - AssertionKnown: 0, - Random : 0, - Skip: 0, - Slow: 0, -}; -var gTotalTests = 0; -var gState; +var gBrowserIsRemote; +var gHaveCanvasSnapshot = false; // Plugin layers can be updated asynchronously, so to make sure that all // layer surfaces have the right content, we need to listen for explicit // "MozPaintWait" and "MozPaintWaitFinished" events that signal when it's OK // to take snapshots. We cannot take a snapshot while the number of // "MozPaintWait" events fired exceeds the number of "MozPaintWaitFinished" // events fired. We count the number of such excess events here. When // the counter reaches zero we call gExplicitPendingPaintsCompleteHook. var gExplicitPendingPaintCount = 0; var gExplicitPendingPaintsCompleteHook; var gCurrentURL; +var gCurrentTestType; +var gTimeoutHook = null; var gFailureTimeout = null; var gFailureReason; -var gTestLog = []; -var gServer; -var gCount = 0; var gAssertionCount = 0; -var gIOService; var gDebug; -var gWindowUtils; var gCurrentTestStartTime; -var gSlowestTestTime = 0; -var gSlowestTestURL; var gClearingForAssertionCheck = false; -var gDrawWindowFlags; - -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 -const EXPECTED_PASS = 0; -const EXPECTED_FAIL = 1; -const EXPECTED_RANDOM = 2; -const EXPECTED_DEATH = 3; // test must be skipped to avoid e.g. crash/hang - -const gProtocolRE = /^\w+:/; - -var HTTP_SERVER_PORT = 4444; -const HTTP_SERVER_PORTS_TO_TRY = 50; - -// whether to run slow tests or not -var gRunSlowTests = true; - -// whether we should skip caching canvases -var gNoCanvasCache = false; - -var gRecycledCanvases = new Array(); - -// By default we just log to stdout -var gDumpLog = dump; - -function LogWarning(str) -{ - gDumpLog("REFTEST INFO | " + str + "\n"); - gTestLog.push(str); +function markupDocumentViewer() { + return docShell.contentViewer.QueryInterface(CI.nsIMarkupDocumentViewer); } -function LogInfo(str) -{ - // gDumpLog("REFTEST INFO | " + str + "\n"); - gTestLog.push(str); -} - -function FlushTestLog() -{ - for (var i = 0; i < gTestLog.length; ++i) { - gDumpLog("REFTEST INFO | Saved log: " + gTestLog[i] + "\n"); - } - gTestLog = []; +function webNavigation() { + return docShell.QueryInterface(CI.nsIWebNavigation); } -function AllocateCanvas() -{ - var windowElem = document.documentElement; - - if (gRecycledCanvases.length > 0) - return gRecycledCanvases.shift(); - - var canvas = document.createElementNS(XHTML_NS, "canvas"); - var r = gBrowser.getBoundingClientRect(); - canvas.setAttribute("width", Math.ceil(r.width)); - canvas.setAttribute("height", Math.ceil(r.height)); - - return canvas; -} - -function ReleaseCanvas(canvas) -{ - // store a maximum of 2 canvases, if we're not caching - if (!gNoCanvasCache || gRecycledCanvases.length < 2) - gRecycledCanvases.push(canvas); +function windowUtils() { + return content.QueryInterface(CI.nsIInterfaceRequestor) + .getInterface(CI.nsIDOMWindowUtils); } function IDForEventTarget(event) { try { return "'" + event.target.getAttribute('id') + "'"; } catch (ex) { return "<unknown>"; @@ -217,738 +144,106 @@ function PaintWaitFinishedListener(event gExplicitPendingPaintCount = 0; } if (gExplicitPendingPaintCount == 0 && gExplicitPendingPaintsCompleteHook) { gExplicitPendingPaintsCompleteHook(); } } -function OnRefTestLoad() +function OnInitialLoad() { - gBrowser = document.getElementById("browser"); - - /* set the gLoadTimeout */ - try { - var prefs = Components.classes["@mozilla.org/preferences-service;1"]. - getService(Components.interfaces.nsIPrefBranch2); - gLoadTimeout = prefs.getIntPref("reftest.timeout"); - logFile = prefs.getCharPref("reftest.logFile"); - if (logFile) { - try { - MozillaFileLogger.init(logFile); - // Set to mirror to stdout as well as the file - gDumpLog = function (msg) {dump(msg); MozillaFileLogger.log(msg);}; - } - catch(e) { - // If there is a problem, just use stdout - gDumpLog = dump; - } - } - gRemote = prefs.getBoolPref("reftest.remote"); - } - catch(e) { - gLoadTimeout = 5 * 60 * 1000; //5 minutes as per bug 479518 - } - - - /* Support for running a chunk (subset) of tests. In separate try as this is optional */ - try { - gTotalChunks = prefs.getIntPref("reftest.totalChunks"); - gThisChunk = prefs.getIntPref("reftest.thisChunk"); - } - catch(e) { - gTotalChunks = 0; - gThisChunk = 0; - } - - gBrowser.addEventListener("load", OnDocumentLoad, true); - - try { - gWindowUtils = window.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIDOMWindowUtils); - if (gWindowUtils && !gWindowUtils.compareCanvases) - gWindowUtils = null; - } catch (e) { - gWindowUtils = null; - } - - var windowElem = document.documentElement; - - gIOService = CC[IO_SERVICE_CONTRACTID].getService(CI.nsIIOService); - gDebug = CC[DEBUG_CONTRACTID].getService(CI.nsIDebug2); - - if (gRemote) { - gServer = null; - } else { - gServer = CC["@mozilla.org/server/jshttp;1"]. - createInstance(CI.nsIHttpServer); - } - try { - if (gServer) - StartHTTPServer(); - } catch (ex) { - //gBrowser.loadURI('data:text/plain,' + ex); - ++gTestResults.Exception; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); - DoneTests(); - } + removeEventListener("load", OnInitialLoad, true); - // Focus the content browser - gBrowser.focus(); - - // Connect to async rendering notifications - gBrowser.addEventListener("MozPaintWait", PaintWaitListener, true); - gBrowser.addEventListener("MozPaintWaitFinished", PaintWaitFinishedListener, true); - - StartTests(); -} - -function StartHTTPServer() -{ - gServer.registerContentType("sjs", "sjs"); - // We want to try different ports in case the port we want - // is being used. - var tries = HTTP_SERVER_PORTS_TO_TRY; - do { - try { - gServer.start(HTTP_SERVER_PORT); - return; - } catch (ex) { - ++HTTP_SERVER_PORT; - if (--tries == 0) - throw ex; - } - } while (true); -} - -function StartTests() -{ - try { - // Need to read the manifest once we have the final HTTP_SERVER_PORT. - var args = window.arguments[0].wrappedJSObject; + gDebug = CC[DEBUG_CONTRACTID].getService(CI.nsIDebug2); - if ("nocache" in args && args["nocache"]) - gNoCanvasCache = true; - - if ("skipslowtests" in args && args.skipslowtests) - gRunSlowTests = false; - - ReadTopManifest(args.uri); - BuildUseCounts(); - - if (gTotalChunks > 0 && gThisChunk > 0) { - var testsPerChunk = gURLs.length / gTotalChunks; - var start = Math.round((gThisChunk-1) * testsPerChunk); - var end = Math.round(gThisChunk * testsPerChunk); - gURLs = gURLs.slice(start, end); - gDumpLog("REFTEST INFO | Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. ") - gDumpLog("tests " + (start+1) + "-" + end + "/" + gURLs.length + "\n"); - } - gTotalTests = gURLs.length; - - if (!gTotalTests) - throw "No tests to run"; - - gURICanvases = {}; - StartCurrentTest(); - } catch (ex) { - //gBrowser.loadURI('data:text/plain,' + ex); - ++gTestResults.Exception; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); - DoneTests(); - } -} - -function OnRefTestUnload() -{ - gBrowser.removeEventListener("load", OnDocumentLoad, true); - MozillaFileLogger.close(); -} + RegisterMessageListeners(); -// Read all available data from an input stream and return it -// as a string. -function getStreamContent(inputStream) -{ - 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; -} - -// Build the sandbox for fails-if(), etc., condition evaluation. -function BuildConditionSandbox(aURL) { - var sandbox = new Components.utils.Sandbox(aURL.spec); - var xr = CC[NS_XREAPPINFO_CONTRACTID].getService(CI.nsIXULRuntime); - sandbox.isDebugBuild = gDebug.isDebugBuild; - sandbox.xulRuntime = {widgetToolkit: xr.widgetToolkit, OS: xr.OS, __exposedProps__: { widgetToolkit: "r", OS: "r", XPCOMABI: "r", shell: "r" } }; + var initInfo = SendContentReady(); + gBrowserIsRemote = initInfo.remote; - // xr.XPCOMABI throws exception for configurations without full ABI - // support (mobile builds on ARM) - try { - sandbox.xulRuntime.XPCOMABI = xr.XPCOMABI; - } catch(e) { - sandbox.xulRuntime.XPCOMABI = ""; - } - - try { - // nsIGfxInfo is currently only implemented on Windows - sandbox.d2d = CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo).D2DEnabled; - } catch(e) { - sandbox.d2d = false; - } - - if (gWindowUtils && gWindowUtils.layerManagerType != "Basic") - sandbox.layersGPUAccelerated = true; - else - sandbox.layersGPUAccelerated = false; - - // Shortcuts for widget toolkits. - sandbox.cocoaWidget = xr.widgetToolkit == "cocoa"; - sandbox.gtk2Widget = xr.widgetToolkit == "gtk2"; - sandbox.qtWidget = xr.widgetToolkit == "qt"; - sandbox.winWidget = xr.widgetToolkit == "windows"; + addEventListener("load", OnDocumentLoad, true); - var hh = CC[NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX + "http"]. - getService(CI.nsIHttpProtocolHandler); - sandbox.http = { __exposedProps__: {} }; - for each (var prop in [ "userAgent", "appName", "appVersion", - "vendor", "vendorSub", - "product", "productSub", - "platform", "oscpu", "language", "misc" ]) { - sandbox.http[prop] = hh[prop]; - sandbox.http.__exposedProps__[prop] = "r"; - } - // see if we have the test plugin available, - // and set a sandox prop accordingly - sandbox.haveTestPlugin = false; - for (var i = 0; i < navigator.mimeTypes.length; i++) { - if (navigator.mimeTypes[i].type == "application/x-test" && - navigator.mimeTypes[i].enabledPlugin != null && - navigator.mimeTypes[i].enabledPlugin.name == "Test Plug-in") { - sandbox.haveTestPlugin = true; - break; - } - } - - // Set a flag on sandbox if the windows default theme is active - var box = document.createElement("box"); - box.setAttribute("id", "_box_windowsDefaultTheme"); - document.documentElement.appendChild(box); - sandbox.windowsDefaultTheme = (getComputedStyle(box, null).display == "none"); - document.documentElement.removeChild(box); - - var prefs = CC["@mozilla.org/preferences-service;1"]. - getService(CI.nsIPrefBranch2); - try { - sandbox.nativeThemePref = !prefs.getBoolPref("mozilla.widget.disable-native-theme"); - } catch (e) { - sandbox.nativeThemePref = true; - } - - sandbox.prefs = { - __exposedProps__: { - getBoolPref: 'r', - getIntPref: 'r', - }, - _prefs: prefs, - getBoolPref: function(p) { return this._prefs.getBoolPref(p); }, - getIntPref: function(p) { return this._prefs.getIntPref(p); } - } - - sandbox.testPluginIsOOP = function () { - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - var prefservice = Components.classes["@mozilla.org/preferences-service;1"] - .getService(CI.nsIPrefBranch); - - var testPluginIsOOP = false; - if (navigator.platform.indexOf("Mac") == 0) { - var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"] - .getService(CI.nsIXULAppInfo) - .QueryInterface(CI.nsIXULRuntime); - if (xulRuntime.XPCOMABI.match(/x86-/)) { - try { - testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.i386.test.plugin"); - } catch (e) { - testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.i386"); - } - } - else if (xulRuntime.XPCOMABI.match(/x86_64-/)) { - try { - testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.x86_64.test.plugin"); - } catch (e) { - testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.x86_64"); - } - } - } - else { - testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled"); - } - - return testPluginIsOOP; - }; - - gDumpLog("REFTEST INFO | Dumping JSON representation of sandbox \n"); - gDumpLog("REFTEST INFO | " + JSON.stringify(sandbox) + " \n"); - - return sandbox; -} - -function ReadTopManifest(aFileURL) -{ - gURLs = new Array(); - var url = gIOService.newURI(aFileURL, null, null); - if (!url) - throw "Expected a file or http URL for the manifest."; - ReadManifest(url); + addEventListener("MozPaintWait", PaintWaitListener, true); + addEventListener("MozPaintWaitFinished", PaintWaitFinishedListener, true); + + LogWarning("Using browser remote="+ gBrowserIsRemote +"\n"); } -// Note: If you materially change the reftest manifest parsing, -// please keep the parser in print-manifest-dirs.py in sync. -function ReadManifest(aURL) +function StartTestURI(type, uri, timeout) { - var secMan = CC[NS_SCRIPTSECURITYMANAGER_CONTRACTID] - .getService(CI.nsIScriptSecurityManager); - - var listURL = aURL; - var channel = gIOService.newChannelFromURI(aURL); - var inputStream = channel.open(); - if (channel instanceof Components.interfaces.nsIHttpChannel - && channel.responseStatus != 200) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | HTTP ERROR : " + - channel.responseStatus + "\n"); - } - var streamBuf = getStreamContent(inputStream); - inputStream.close(); - var lines = streamBuf.split(/(\n|\r|\r\n)/); - - // Build the sandbox for fails-if(), etc., condition evaluation. - var sandbox = BuildConditionSandbox(aURL); - - var lineNo = 0; - var urlprefix = ""; - for each (var str in lines) { - ++lineNo; - if (str.charAt(0) == "#") - continue; // entire line was a comment - var i = str.search(/\s+#/); - if (i >= 0) - str = str.substring(0, i); - // strip leading and trailing whitespace - str = str.replace(/^\s*/, '').replace(/\s*$/, ''); - if (!str || str == "") - continue; - var items = str.split(/\s+/); // split on whitespace - - 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; - } - - var expected_status = EXPECTED_PASS; - var allow_silent_fail = false; - var minAsserts = 0; - var maxAsserts = 0; - var slow = false; - while (items[0].match(/^(fails|random|skip|asserts|slow|silentfail)/)) { - var item = items.shift(); - var stat; - var cond; - var m = item.match(/^(fails|random|skip|silentfail)-if(\(.*\))$/); - if (m) { - stat = m[1]; - // Note: m[2] contains the parentheses, and we want them. - cond = Components.utils.evalInSandbox(m[2], sandbox); - } else if (item.match(/^(fails|random|skip)$/)) { - stat = item; - cond = true; - } 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)); - } - } else if (item == "slow") { - cond = false; - slow = true; - } else if ((m = item.match(/^slow-if\((.*?)\)$/))) { - cond = false; - if (Components.utils.evalInSandbox("(" + m[1] + ")", sandbox)) - slow = true; - } else if (item == "silentfail") { - cond = false; - allow_silent_fail = true; - } else { - throw "Error 1 in manifest file " + aURL.spec + " line " + lineNo; - } - - if (cond) { - if (stat == "fails") { - expected_status = EXPECTED_FAIL; - } else if (stat == "random") { - expected_status = EXPECTED_RANDOM; - } else if (stat == "skip") { - expected_status = EXPECTED_DEATH; - } else if (stat == "silentfail") { - allow_silent_fail = true; - } - } - } - - if (minAsserts > maxAsserts) { - throw "Bad range in manifest file " + aURL.spec + " line " + lineNo; - } - - var runHttp = false; - var httpDepth; - if (items[0] == "HTTP") { - runHttp = (aURL.scheme == "file"); // We can't yet run the local HTTP server - // for non-local reftests. - httpDepth = 0; - items.shift(); - } else if (items[0].match(/HTTP\(\.\.(\/\.\.)*\)/)) { - // Accept HTTP(..), HTTP(../..), HTTP(../../..), etc. - runHttp = (aURL.scheme == "file"); // We can't yet run the local HTTP server - // for non-local reftests. - httpDepth = (items[0].length - 5) / 3; - items.shift(); - } - - // 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]; - } - } - - if (items[0] == "include") { - if (items.length != 2 || runHttp) - throw "Error 2 in manifest file " + aURL.spec + " line " + lineNo; - var incURI = gIOService.newURI(items[1], null, listURL); - secMan.checkLoadURI(aURL, incURI, - CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); - ReadManifest(incURI); - } else if (items[0] == TYPE_LOAD) { - if (items.length != 2 || - (expected_status != EXPECTED_PASS && - expected_status != EXPECTED_DEATH)) - throw "Error 3 in manifest file " + aURL.spec + " line " + lineNo; - var [testURI] = runHttp - ? ServeFiles(aURL, httpDepth, - listURL, [items[1]]) - : [gIOService.newURI(items[1], null, listURL)]; - var prettyPath = runHttp - ? gIOService.newURI(items[1], null, listURL).spec - : testURI.spec; - secMan.checkLoadURI(aURL, testURI, - CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); - gURLs.push( { type: TYPE_LOAD, - expected: expected_status, - allowSilentFail: allow_silent_fail, - prettyPath: prettyPath, - minAsserts: minAsserts, - maxAsserts: maxAsserts, - slow: slow, - url1: testURI, - url2: null } ); - } else if (items[0] == TYPE_SCRIPT) { - if (items.length != 2) - throw "Error 4 in manifest file " + aURL.spec + " line " + lineNo; - var [testURI] = runHttp - ? ServeFiles(aURL, httpDepth, - listURL, [items[1]]) - : [gIOService.newURI(items[1], null, listURL)]; - var prettyPath = runHttp - ? gIOService.newURI(items[1], null, listURL).spec - : testURI.spec; - secMan.checkLoadURI(aURL, testURI, - CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); - gURLs.push( { type: TYPE_SCRIPT, - expected: expected_status, - allowSilentFail: allow_silent_fail, - prettyPath: prettyPath, - minAsserts: minAsserts, - maxAsserts: maxAsserts, - slow: slow, - url1: testURI, - url2: null } ); - } else if (items[0] == TYPE_REFTEST_EQUAL || items[0] == TYPE_REFTEST_NOTEQUAL) { - if (items.length != 3) - throw "Error 5 in manifest file " + aURL.spec + " line " + lineNo; - var [testURI, refURI] = runHttp - ? ServeFiles(aURL, httpDepth, - listURL, [items[1], items[2]]) - : [gIOService.newURI(items[1], null, listURL), - gIOService.newURI(items[2], null, listURL)]; - var prettyPath = runHttp - ? gIOService.newURI(items[1], null, listURL).spec - : testURI.spec; - secMan.checkLoadURI(aURL, testURI, - CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); - secMan.checkLoadURI(aURL, refURI, - CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); - gURLs.push( { type: items[0], - expected: expected_status, - allowSilentFail: allow_silent_fail, - prettyPath: prettyPath, - minAsserts: minAsserts, - maxAsserts: maxAsserts, - slow: slow, - url1: testURI, - url2: refURI } ); - } else { - throw "Error 6 in manifest file " + aURL.spec + " line " + lineNo; - } - } -} - -function AddURIUseCount(uri) -{ - if (uri == null) - return; - - var spec = uri.spec; - if (spec in gURIUseCounts) { - gURIUseCounts[spec]++; - } else { - gURIUseCounts[spec] = 1; - } -} - -function BuildUseCounts() -{ - gURIUseCounts = {}; - for (var i = 0; i < gURLs.length; ++i) { - var url = gURLs[i]; - if (url.expected != EXPECTED_DEATH && - (url.type == TYPE_REFTEST_EQUAL || - url.type == TYPE_REFTEST_NOTEQUAL)) { - AddURIUseCount(gURLs[i].url1); - AddURIUseCount(gURLs[i].url2); - } - } -} - -function ServeFiles(manifestURL, depth, aURL, files) -{ - var listURL = aURL.QueryInterface(CI.nsIFileURL); - var directory = listURL.file.parent; - - // 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; - } - - gCount++; - var path = "/" + Date.now() + "/" + gCount; - gServer.registerDirectory(path + "/", directory); - - var secMan = CC[NS_SCRIPTSECURITYMANAGER_CONTRACTID] - .getService(CI.nsIScriptSecurityManager); - - var testbase = gIOService.newURI("http://localhost:" + HTTP_SERVER_PORT + - path + dirPath, - null, null); - - function FileToURI(file) - { - // Only serve relative URIs via the HTTP server, not absolute - // ones like about:blank. - var testURI = gIOService.newURI(file, null, testbase); - - // XXX necessary? manifestURL guaranteed to be file, others always HTTP - secMan.checkLoadURI(manifestURL, testURI, - CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); - - return testURI; - } - - return files.map(FileToURI); -} - -function StartCurrentTest() -{ - gTestLog = []; - - // make sure we don't run tests that are expected to kill the browser - while (gURLs.length > 0) { - var test = gURLs[0]; - if (test.expected == EXPECTED_DEATH) { - ++gTestResults.Skip; - gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + " | (SKIP)\n"); - gURLs.shift(); - } else if (test.slow && !gRunSlowTests) { - ++gTestResults.Slow; - gDumpLog("REFTEST TEST-KNOWN-SLOW | " + test.url1.spec + " | (SLOW)\n"); - gURLs.shift(); - } else { - break; - } - } - - if (gURLs.length == 0) { - DoneTests(); - } - else { - var currentTest = gTotalTests - gURLs.length; - document.title = "reftest: " + currentTest + " / " + gTotalTests + - " (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)"; - StartCurrentURI(1); - } -} - -function StartCurrentURI(aState) -{ - gCurrentTestStartTime = Date.now(); - if (gFailureTimeout != null) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + - "| program error managing timeouts\n"); - ++gTestResults.Exception; - } - gFailureTimeout = setTimeout(LoadFailed, gLoadTimeout); - gFailureReason = "timed out waiting for onload to fire"; - - gState = aState; - gCurrentURL = gURLs[0]["url" + aState].spec; // Reset gExplicitPendingPaintCount in case there was a timeout or // the count is out of sync for some other reason if (gExplicitPendingPaintCount != 0) { LogWarning("Resetting gExplicitPendingPaintCount to zero (currently " + gExplicitPendingPaintCount + "\n"); gExplicitPendingPaintCount = 0; } - if (gURICanvases[gCurrentURL] && - (gURLs[0].type == TYPE_REFTEST_EQUAL || - gURLs[0].type == TYPE_REFTEST_NOTEQUAL) && - gURLs[0].maxAsserts == 0) { - // Pretend the document loaded --- RecordResult will notice - // there's already a canvas for this URL - setTimeout(RecordResult, 0); - } else { - gDumpLog("REFTEST TEST-START | " + gCurrentURL + "\n"); - LogInfo("START " + gCurrentURL); - gBrowser.loadURI(gCurrentURL); - } -} - -function DoneTests() -{ - gDumpLog("REFTEST FINISHED: Slowest test took " + gSlowestTestTime + - "ms (" + gSlowestTestURL + ")\n"); + gCurrentTestType = type; + gCurrentURL = uri; - gDumpLog("REFTEST INFO | Result summary:\n"); - var count = gTestResults.Pass + gTestResults.LoadOnly; - gDumpLog("REFTEST INFO | Successful: " + count + " (" + - gTestResults.Pass + " pass, " + - gTestResults.LoadOnly + " load only)\n"); - count = gTestResults.Exception + gTestResults.FailedLoad + - gTestResults.UnexpectedFail + gTestResults.UnexpectedPass + - gTestResults.AssertionUnexpected + - gTestResults.AssertionUnexpectedFixed; - gDumpLog("REFTEST INFO | Unexpected: " + count + " (" + - gTestResults.UnexpectedFail + " unexpected fail, " + - gTestResults.UnexpectedPass + " unexpected pass, " + - gTestResults.AssertionUnexpected + " unexpected asserts, " + - gTestResults.AssertionUnexpectedFixed + " unexpected fixed asserts, " + - gTestResults.FailedLoad + " failed load, " + - gTestResults.Exception + " exception)\n"); - count = gTestResults.KnownFail + gTestResults.AssertionKnown + - gTestResults.Random + gTestResults.Skip + gTestResults.Slow; - gDumpLog("REFTEST INFO | Known problems: " + count + " (" + - gTestResults.KnownFail + " known fail, " + - gTestResults.AssertionKnown + " known asserts, " + - gTestResults.Random + " random, " + - gTestResults.Skip + " skipped, " + - gTestResults.Slow + " slow)\n"); + gCurrentTestStartTime = Date.now(); + if (gFailureTimeout != null) { + SendException("program error managing timeouts\n"); + } + gFailureTimeout = setTimeout(LoadFailed, timeout); - gDumpLog("REFTEST INFO | Total canvas count = " + gRecycledCanvases.length + "\n"); - - gDumpLog("REFTEST TEST-START | Shutdown\n"); - function onStopped() { - goQuitApplication(); - } - if (gServer) - gServer.stop(onStopped); - else - onStopped(); + LoadURI(gCurrentURL); } function setupZoom(contentRootElement) { if (!contentRootElement || !contentRootElement.hasAttribute('reftest-zoom')) return; - gBrowser.markupDocumentViewer.fullZoom = + markupDocumentViewer().fullZoom = contentRootElement.getAttribute('reftest-zoom'); } function resetZoom() { - gBrowser.markupDocumentViewer.fullZoom = 1.0; + markupDocumentViewer().fullZoom = 1.0; } function doPrintMode(contentRootElement) { // use getAttribute because className works differently in HTML and SVG return contentRootElement && contentRootElement.hasAttribute('class') && contentRootElement.getAttribute('class').split(/\s+/) .indexOf("reftest-print") != -1; } function setupPrintMode() { - var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] - .getService(Components.interfaces.nsIPrintSettingsService); + var PSSVC = + CC[PRINTSETTINGS_CONTRACTID].getService(CI.nsIPrintSettingsService); var ps = PSSVC.newPrintSettings; ps.paperWidth = 5; ps.paperHeight = 3; // Override any os-specific unwriteable margins ps.unwriteableMarginTop = 0; ps.unwriteableMarginLeft = 0; ps.unwriteableMarginBottom = 0; ps.unwriteableMarginRight = 0; ps.headerStrLeft = ""; ps.headerStrCenter = ""; ps.headerStrRight = ""; ps.footerStrLeft = ""; ps.footerStrCenter = ""; ps.footerStrRight = ""; - gBrowser.docShell.contentViewer.setPageMode(true, ps); + docShell.contentViewer.setPageMode(true, ps); } function shouldWaitForExplicitPaintWaiters() { return gExplicitPendingPaintCount > 0; } function shouldWaitForPendingPaints() { - // if gCurrentCanvas is null, we're not taking snapshots so there is - // no need to wait for pending paints to be flushed. - return gCurrentCanvas && gWindowUtils.isMozAfterPaintPending; + // if gHaveCanvasSnapshot is false, we're not taking snapshots so + // there is no need to wait for pending paints to be flushed. + return gHaveCanvasSnapshot && windowUtils().isMozAfterPaintPending; } function shouldWaitForReftestWaitRemoval(contentRootElement) { // use getAttribute because className works differently in HTML and SVG return contentRootElement && contentRootElement.hasAttribute('class') && contentRootElement.getAttribute('class').split(/\s+/) .indexOf("reftest-wait") != -1; @@ -963,16 +258,17 @@ const STATE_WAITING_TO_FIRE_INVALIDATE_E const STATE_WAITING_FOR_REFTEST_WAIT_REMOVAL = 1; // When all MozAfterPaint events and all explicit paint waits are flushed, we're // done and can move to the COMPLETED state. const STATE_WAITING_TO_FINISH = 2; const STATE_COMPLETED = 3; function WaitForTestEnd(contentRootElement, inPrintMode) { var stopAfterPaintReceived = false; + var currentDoc = content.document; var state = STATE_WAITING_TO_FIRE_INVALIDATE_EVENT; function FlushRendering() { var anyPendingPaintsGeneratedInDescendants = false; function flushWindow(win) { var utils = win.QueryInterface(CI.nsIInterfaceRequestor) .getInterface(CI.nsIDOMWindowUtils); @@ -990,32 +286,33 @@ function WaitForTestEnd(contentRootEleme anyPendingPaintsGeneratedInDescendants = true; } for (var i = 0; i < win.frames.length; ++i) { flushWindow(win.frames[i]); } } - flushWindow(gBrowser.contentWindow); + flushWindow(content); if (anyPendingPaintsGeneratedInDescendants && - !gWindowUtils.isMozAfterPaintPending) { + !windowUtils().isMozAfterPaintPending) { LogWarning("Internal error: descendant frame generated a MozAfterPaint event, but the root document doesn't have one!"); } } function AfterPaintListener(event) { LogInfo("AfterPaintListener in " + event.target.document.location.href); - if (event.target.document != document) { + if (event.target.document != currentDoc) { // ignore paint events for subframes or old documents in the window. // Invalidation in subframes will cause invalidation in the toplevel document anyway. return; } - UpdateCurrentCanvasForEvent(event); + + SendUpdateCanvasForEvent(event); // These events are fired immediately after a paint. Don't // confuse ourselves by firing synchronously if we triggered the // paint ourselves. setTimeout(MakeProgress, 0); } function AttrModifiedListener() { LogInfo("AttrModifiedListener fired"); @@ -1030,19 +327,19 @@ function WaitForTestEnd(contentRootEleme LogInfo("ExplicitPaintsCompleteListener fired"); // Since this can fire while painting, don't confuse ourselves by // firing synchronously. It's fine to do this asynchronously. setTimeout(MakeProgress, 0); } function RemoveListeners() { // OK, we can end the test now. - window.removeEventListener("MozAfterPaint", AfterPaintListener, false); + removeEventListener("MozAfterPaint", AfterPaintListener, false); if (contentRootElement) { - contentRootElement.removeEventListener("DOMAttrModified", AttrModifiedListener, false); + contentRootElement.removeEventListener("DOMAttrModified", AttrModifiedListener, false); } gExplicitPendingPaintsCompleteHook = null; gTimeoutHook = null; // Make sure we're in the COMPLETED state just in case // (this may be called via the test-timeout hook) state = STATE_COMPLETED; } @@ -1071,18 +368,19 @@ function WaitForTestEnd(contentRootEleme LogInfo("MakeProgress: waiting for MozAfterPaint"); } return; } state = STATE_WAITING_FOR_REFTEST_WAIT_REMOVAL; var hasReftestWait = shouldWaitForReftestWaitRemoval(contentRootElement); // Notify the test document that now is a good time to test some invalidation + LogInfo("MakeProgress: dispatching MozReftestInvalidate"); if (contentRootElement) { - var notification = document.createEvent("Events"); + var notification = content.document.createEvent("Events"); notification.initEvent("MozReftestInvalidate", true, false); contentRootElement.dispatchEvent(notification); } if (hasReftestWait && !shouldWaitForReftestWaitRemoval(contentRootElement)) { // MozReftestInvalidate handler removed reftest-wait. // We expect something to have been invalidated... FlushRendering(); if (!shouldWaitForPendingPaints() && !shouldWaitForExplicitPaintWaiters()) { @@ -1130,35 +428,35 @@ function WaitForTestEnd(contentRootEleme gFailureReason = "timed out while taking snapshot (bug in harness?)"; RemoveListeners(); setTimeout(RecordResult, 0); return; } } LogInfo("WaitForTestEnd: Adding listeners"); - window.addEventListener("MozAfterPaint", AfterPaintListener, false); + addEventListener("MozAfterPaint", AfterPaintListener, false); // If contentRootElement is null then shouldWaitForReftestWaitRemoval will // always return false so we don't need a listener anyway if (contentRootElement) { contentRootElement.addEventListener("DOMAttrModified", AttrModifiedListener, false); } gExplicitPendingPaintsCompleteHook = ExplicitPaintsCompleteListener; gTimeoutHook = RemoveListeners; // Take a full snapshot now that all our listeners are set up. This // ensures it's impossible for us to miss updates between taking the snapshot // and adding our listeners. - InitCurrentCanvasWithSnapshot(); + SendInitCanvasWithSnapshot(); MakeProgress(); } function OnDocumentLoad(event) { - var currentDoc = gBrowser.contentDocument; + var currentDoc = content.document; if (event.target != currentDoc) // Ignore load events for subframes. return; if (gClearingForAssertionCheck && currentDoc.location.href == BLANK_URL_FOR_CLEARING) { DoAssertionCheck(); return; @@ -1174,17 +472,17 @@ function OnDocumentLoad(event) setupZoom(contentRootElement); var inPrintMode = false; function AfterOnLoadScripts() { // Take a snapshot now. We need to do this before we check whether // we should wait, since this might trigger dispatching of // MozPaintWait events and make shouldWaitForExplicitPaintWaiters() true // below. - var painted = InitCurrentCanvasWithSnapshot(); + var painted = SendInitCanvasWithSnapshot(); if (shouldWaitForExplicitPaintWaiters() || (!inPrintMode && doPrintMode(contentRootElement)) || // If we didn't force a paint above, in // InitCurrentCanvasWithSnapshot, so we should wait for a // paint before we consider them done. !painted) { LogInfo("AfterOnLoadScripts belatedly entering WaitForTestEnd"); @@ -1196,110 +494,32 @@ function OnDocumentLoad(event) } if (shouldWaitForReftestWaitRemoval(contentRootElement) || shouldWaitForExplicitPaintWaiters()) { // Go into reftest-wait mode immediately after painting has been // unsuppressed, after the onload event has finished dispatching. gFailureReason = "timed out waiting for test to complete (trying to get into WaitForTestEnd)"; LogInfo("OnDocumentLoad triggering WaitForTestEnd"); - setTimeout(WaitForTestEnd, 0, contentRootElement, inPrintMode); + setTimeout(function () { WaitForTestEnd(contentRootElement, inPrintMode); }, 0); } else { if (doPrintMode(contentRootElement)) { LogInfo("OnDocumentLoad setting up print mode"); setupPrintMode(); inPrintMode = true; } // Since we can't use a bubbling-phase load listener from chrome, // this is a capturing phase listener. So do setTimeout twice, the // first to get us after the onload has fired in the content, and // the second to get us after any setTimeout(foo, 0) in the content. gFailureReason = "timed out waiting for test to complete (waiting for onload scripts to complete)"; LogInfo("OnDocumentLoad triggering AfterOnLoadScripts"); - setTimeout(setTimeout, 0, AfterOnLoadScripts, 0); - } -} - -function UpdateCanvasCache(url, canvas) -{ - var spec = url.spec; - - --gURIUseCounts[spec]; - - if (gNoCanvasCache || gURIUseCounts[spec] == 0) { - ReleaseCanvas(canvas); - delete gURICanvases[spec]; - } else if (gURIUseCounts[spec] > 0) { - gURICanvases[spec] = canvas; - } else { - throw "Use counts were computed incorrectly"; - } -} - -// 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. -function DoDrawWindow(ctx, x, y, w, h) -{ - var flags = ctx.DRAWWINDOW_DRAW_CARET | ctx.DRAWWINDOW_DRAW_VIEW; - var testRect = gBrowser.getBoundingClientRect(); - if (0 <= testRect.left && - 0 <= testRect.top && - window.innerWidth >= testRect.right && - window.innerHeight >= testRect.bottom) { - // 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; + setTimeout(function () { setTimeout(AfterOnLoadScripts, 0); }, 0); } - - 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. - gDumpLog("REFTEST INFO | WARNING: USE_WIDGET_LAYERS disabled\n"); - } - gDumpLog("REFTEST INFO | drawWindow flags = " + flagsStr + - "; window size = " + window.innerWidth + "," + window.innerHeight + - "; test browser size = " + testRect.width + "," + testRect.height + - "\n"); - } - - LogInfo("DoDrawWindow " + x + "," + y + "," + w + "," + h); - ctx.drawWindow(window, x, y, w, h, "rgb(255,255,255)", - gDrawWindowFlags); -} - -function InitCurrentCanvasWithSnapshot() -{ - if (gURLs[0].type == TYPE_LOAD || gURLs[0].type == TYPE_SCRIPT) { - // We don't want to snapshot this kind of test - return false; - } - - if (!gCurrentCanvas) { - gCurrentCanvas = AllocateCanvas(); - } - - var ctx = gCurrentCanvas.getContext("2d"); - DoDrawWindow(ctx, 0, 0, gCurrentCanvas.width, gCurrentCanvas.height); - return true; -} - -function roundTo(x, fraction) -{ - return Math.round(x/fraction)*fraction; } function UpdateCurrentCanvasForEvent(event) { if (!gCurrentCanvas) return; var ctx = gCurrentCanvas.getContext("2d"); @@ -1318,265 +538,246 @@ function UpdateCurrentCanvasForEvent(eve ctx.restore(); } } function RecordResult() { LogInfo("RecordResult fired"); - // Keep track of which test was slowest, and how long it took. var currentTestRunTime = Date.now() - gCurrentTestStartTime; - if (currentTestRunTime > gSlowestTestTime) { - gSlowestTestTime = currentTestRunTime; - gSlowestTestURL = gCurrentURL; - } clearTimeout(gFailureTimeout); gFailureReason = null; gFailureTimeout = null; - // Not 'const ...' because of 'EXPECTED_*' value dependency. - var outputs = {}; - const randomMsg = "(EXPECTED RANDOM)"; - outputs[EXPECTED_PASS] = { - true: {s: "TEST-PASS" , n: "Pass"}, - false: {s: "TEST-UNEXPECTED-FAIL" , n: "UnexpectedFail"} - }; - outputs[EXPECTED_FAIL] = { - true: {s: "TEST-UNEXPECTED-PASS" , n: "UnexpectedPass"}, - false: {s: "TEST-KNOWN-FAIL" , n: "KnownFail"} - }; - outputs[EXPECTED_RANDOM] = { - true: {s: "TEST-PASS" + randomMsg , n: "Random"}, - false: {s: "TEST-KNOWN-FAIL" + randomMsg, n: "Random"} - }; - var output; - - if (gURLs[0].type == TYPE_LOAD) { - ++gTestResults.LoadOnly; - gDumpLog("REFTEST TEST-PASS | " + gURLs[0].prettyPath + " | (LOAD ONLY)\n"); - gCurrentCanvas = null; - FinishTestItem(); - return; - } - if (gURLs[0].type == TYPE_SCRIPT) { - var missing_msg = false; - var testwindow = gBrowser.contentWindow; - expected = gURLs[0].expected; + if (gCurrentTestType == TYPE_SCRIPT) { + var error = ''; + var testwindow = content; if (testwindow.wrappedJSObject) testwindow = testwindow.wrappedJSObject; var testcases; - if (!testwindow.getTestCases || typeof testwindow.getTestCases != "function") { // Force an unexpected failure to alert the test author to fix the test. - expected = EXPECTED_PASS; - missing_msg = "test must provide a function getTestCases(). (SCRIPT)\n"; + error = "test must provide a function getTestCases(). (SCRIPT)\n"; } else if (!(testcases = testwindow.getTestCases())) { // Force an unexpected failure to alert the test author to fix the test. - expected = EXPECTED_PASS; - missing_msg = "test's getTestCases() must return an Array-like Object. (SCRIPT)\n"; + error = "test's getTestCases() must return an Array-like Object. (SCRIPT)\n"; } else if (testcases.length == 0) { // 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) - missing_msg = "No test results reported. (SCRIPT)\n"; - else - gDumpLog("REFTEST INFO | An expected silent failure occurred \n"); - } - - if (missing_msg) { - output = outputs[expected][false]; - ++gTestResults[output.n]; - var result = "REFTEST " + output.s + " | " + - gURLs[0].prettyPath + " | " + // the URL being tested - missing_msg; - - gDumpLog(result); - FinishTestItem(); - return; + // failure, the driver will report an error. } - var results = testcases.map(function(test) { - return { passed: test.testPassed(), description: test.testDescription()}; - }); - var anyFailed = results.some(function(result) { return !result.passed; }); - 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; - results.forEach(function(result) { - var output = outputPair[result.passed]; - - ++gTestResults[output.n]; - result = "REFTEST " + output.s + " | " + - gURLs[0].prettyPath + " | " + // the URL being tested - result.description + " item " + (++index) + "\n"; - gDumpLog(result); - }); - - if (anyFailed && expected == EXPECTED_PASS) { - FlushTestLog(); + var results = [ ]; + if (!error) { + // FIXME/bug 618176: temporary workaround + for (var i = 0; i < testcases.length; ++i) { + var test = testcases[i]; + results.push({ passed: test.testPassed(), + description: test.testDescription() }); + } + //results = testcases.map(function(test) { + // return { passed: test.testPassed(), + // description: test.testDescription() }; } + SendScriptResults(currentTestRunTime, error, results); FinishTestItem(); return; } - if (gURICanvases[gCurrentURL]) { - gCurrentCanvas = gURICanvases[gCurrentURL]; - } - if (gState == 1) { - gCanvas1 = gCurrentCanvas; - } else { - gCanvas2 = gCurrentCanvas; - } - gCurrentCanvas = null; - - resetZoom(); - - switch (gState) { - case 1: - // First document has been loaded. - // Proceed to load the second document. - - StartCurrentURI(2); - break; - case 2: - // Both documents have been loaded. Compare the renderings and see - // if the comparison result matches the expected result specified - // in the manifest. - - // number of different pixels - var differences; - // whether the two renderings match: - var equal; - - if (gWindowUtils) { - differences = gWindowUtils.compareCanvases(gCanvas1, gCanvas2, {}); - equal = (differences == 0); - } else { - differences = -1; - var k1 = gCanvas1.toDataURL(); - var k2 = gCanvas2.toDataURL(); - equal = (k1 == k2); - } - - // whether the comparison result matches what is in the manifest - var test_passed = (equal == (gURLs[0].type == TYPE_REFTEST_EQUAL)); - // what is expected on this platform (PASS, FAIL, or RANDOM) - var expected = gURLs[0].expected; - output = outputs[expected][test_passed]; - - ++gTestResults[output.n]; - - var result = "REFTEST " + output.s + " | " + - gURLs[0].prettyPath + " | "; // the URL being tested - switch (gURLs[0].type) { - case TYPE_REFTEST_NOTEQUAL: - result += "image comparison (!=) "; - break; - case TYPE_REFTEST_EQUAL: - result += "image comparison (==) "; - break; - } - gDumpLog(result + "\n"); - - if (!test_passed && expected == EXPECTED_PASS || - test_passed && expected == EXPECTED_FAIL) { - if (!equal) { - gDumpLog("REFTEST IMAGE 1 (TEST): " + gCanvas1.toDataURL() + "\n"); - gDumpLog("REFTEST IMAGE 2 (REFERENCE): " + gCanvas2.toDataURL() + "\n"); - gDumpLog("REFTEST number of differing pixels: " + differences + "\n"); - } else { - gDumpLog("REFTEST IMAGE: " + gCanvas1.toDataURL() + "\n"); - } - } - - if (!test_passed && expected == EXPECTED_PASS) { - FlushTestLog(); - } - - UpdateCanvasCache(gURLs[0].url1, gCanvas1); - UpdateCanvasCache(gURLs[0].url2, gCanvas2); - - FinishTestItem(); - break; - default: - throw "Unexpected state."; - } + SendTestDone(currentTestRunTime); + FinishTestItem(); } function LoadFailed() { if (gTimeoutHook) { gTimeoutHook(); } gFailureTimeout = null; - ++gTestResults.FailedLoad; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + - gURLs[0]["url" + gState].spec + " | " + gFailureReason + "\n"); - FlushTestLog(); - FinishTestItem(); + SendFailedLoad(gFailureReason); } function FinishTestItem() { - // Replace document with BLANK_URL_FOR_CLEARING in case there are - // assertions when unloading. - gDumpLog("REFTEST INFO | Loading a blank page\n"); - gClearingForAssertionCheck = true; - gBrowser.loadURI(BLANK_URL_FOR_CLEARING); + gHaveCanvasSnapshot = false; } function DoAssertionCheck() { gClearingForAssertionCheck = false; + var numAsserts = 0; if (gDebug.isDebugBuild) { var newAssertionCount = gDebug.assertionCount; - var numAsserts = newAssertionCount - gAssertionCount; + numAsserts = newAssertionCount - gAssertionCount; gAssertionCount = newAssertionCount; - - var minAsserts = gURLs[0].minAsserts; - var maxAsserts = gURLs[0].maxAsserts; + } + SendAssertionCount(numAsserts); +} - var expectedAssertions = "expected " + minAsserts; - if (minAsserts != maxAsserts) { - expectedAssertions += " to " + maxAsserts; - } - expectedAssertions += " assertions"; +function LoadURI(uri) +{ + var flags = webNavigation().LOAD_FLAGS_NONE; + webNavigation().loadURI(uri, flags, null, null, null); +} - if (numAsserts < minAsserts) { - ++gTestResults.AssertionUnexpectedFixed; - gDumpLog("REFTEST TEST-UNEXPECTED-PASS | " + gURLs[0].prettyPath + - " | assertion count " + numAsserts + " is less than " + - expectedAssertions + "\n"); - } else if (numAsserts > maxAsserts) { - ++gTestResults.AssertionUnexpected; - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath + - " | assertion count " + numAsserts + " is more than " + - expectedAssertions + "\n"); - } else if (numAsserts != 0) { - ++gTestResults.AssertionKnown; - gDumpLog("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath + - " | assertion count " + numAsserts + " matches " + - expectedAssertions + "\n"); - } +function LogWarning(str) +{ + sendAsyncMessage("reftest:Log", { type: "warning", msg: str }); +} + +function LogInfo(str) +{ + sendAsyncMessage("reftest:Log", { type: "info", msg: str }); +} + +var gDummyCanvas = null; +function SynchronizeForSnapshot() +{ + if (gDummyCanvas == null) { + gDummyCanvas = content.document.createElementNS(XHTML_NS, "canvas"); + gDummyCanvas.setAttribute("width", 1); + gDummyCanvas.setAttribute("height", 1); } - // And start the next test. - gURLs.shift(); - StartCurrentTest(); + var ctx = gDummyCanvas.getContext("2d"); + var flags = ctx.DRAWWINDOW_DRAW_CARET | ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_USE_WIDGET_LAYERS; + ctx.drawWindow(content, 0, 0, 1, 1, "rgb(255,255,255)", flags); +} + +function RegisterMessageListeners() +{ + addMessageListener( + "reftest:Clear", + function (m) { RecvClear() } + ); + addMessageListener( + "reftest:LoadScriptTest", + function (m) { RecvLoadScriptTest(m.json.uri, m.json.timeout); } + ); + addMessageListener( + "reftest:LoadTest", + function (m) { RecvLoadTest(m.json.type, m.json.uri, m.json.timeout); } + ); + addMessageListener( + "reftest:ResetZoom", + function (m) { RecvResetZoom(); } + ); +} + +function RecvClear() +{ + gClearingForAssertionCheck = true; + LoadURI(BLANK_URL_FOR_CLEARING); +} + +function RecvLoadTest(type, uri, timeout) +{ + StartTestURI(type, uri, timeout); +} + +function RecvLoadScriptTest(uri, timeout) +{ + StartTestURI(TYPE_SCRIPT, uri, timeout); +} + +function RecvResetZoom() +{ + resetZoom(); +} + +function SendAssertionCount(numAssertions) +{ + sendAsyncMessage("reftest:AssertionCount", { count: numAssertions }); +} + +function SendContentReady() +{ + return sendSyncMessage("reftest:ContentReady")[0]; +} + +function SendException(what) +{ + sendAsyncMessage("reftest:Exception", { what: what }); +} + +function SendFailedLoad(why) +{ + sendAsyncMessage("reftest:FailedLoad", { why: why }); } + +// Return true if a snapshot was taken. +function SendInitCanvasWithSnapshot() +{ + // If we're in the same process as the top-level XUL window, then + // drawing that window will also update our layers, so no + // synchronization is needed. + // + // NB: this is a test-harness optimization only, it must not + // affect the validity of the tests. + if (gBrowserIsRemote) { + SynchronizeForSnapshot(); + } + + // For in-process browser, we have to make a synchronous request + // here to make the above optimization valid, so that MozWaitPaint + // events dispatched (synchronously) during painting are received + // before we check the paint-wait counter. For out-of-process + // browser though, it doesn't wrt correctness whether this request + // is sync or async. + var ret = sendSyncMessage("reftest:InitCanvasWithSnapshot")[0]; + + gHaveCanvasSnapshot = ret.painted; + return ret.painted; +} + +function SendScriptResults(runtimeMs, error, results) + { + sendAsyncMessage("reftest:ScriptResults", + { runtimeMs: runtimeMs, error: error, results: results }); +} + +function SendTestDone(runtimeMs) +{ + sendAsyncMessage("reftest:TestDone", { runtimeMs: runtimeMs }); +} + +function roundTo(x, fraction) +{ + return Math.round(x/fraction)*fraction; +} + +function SendUpdateCanvasForEvent(event) +{ + var win = content; + var scale = markupDocumentViewer().fullZoom; + + var rects = [ ]; + var rectList = event.clientRects; + for (var i = 0; i < rectList.length; ++i) { + var r = rectList[i]; + // Set left/top/right/bottom to "device pixel" boundaries + var left = Math.floor(roundTo(r.left*scale, 0.001)); + var top = Math.floor(roundTo(r.top*scale, 0.001)); + var right = Math.ceil(roundTo(r.right*scale, 0.001)); + var bottom = Math.ceil(roundTo(r.bottom*scale, 0.001)); + + rects.push({ left: left, top: top, right: right, bottom: bottom }); + } + + // See comments in SendInitCanvasWithSnapshot() re: the split + // logic here. + if (!gBrowserIsRemote) { + sendSyncMessage("reftest:UpdateCanvasForInvalidation", { rects: rects }); + } else { + SynchronizeForSnapshot(); + sendAsyncMessage("reftest:UpdateCanvasForInvalidation", { rects: rects }); + } +} + +addEventListener("load", OnInitialLoad, true);
--- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -36,16 +36,17 @@ * * ***** END LICENSE BLOCK ***** */ const CC = Components.classes; const CI = Components.interfaces; const CR = Components.results; const XHTML_NS = "http://www.w3.org/1999/xhtml"; +const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const NS_LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1"; const NS_GFXINFO_CONTRACTID = "@mozilla.org/gfx/info;1"; const IO_SERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; const DEBUG_CONTRACTID = "@mozilla.org/xpcom/debug;1"; const NS_LOCALFILEINPUTSTREAM_CONTRACTID = "@mozilla.org/network/file-input-stream;1"; const NS_SCRIPTSECURITYMANAGER_CONTRACTID = @@ -62,16 +63,19 @@ var gTimeoutHook = null; var gRemote = false; var gTotalChunks = 0; var gThisChunk = 0; // "<!--CLEAR-->" const BLANK_URL_FOR_CLEARING = "data:text/html,%3C%21%2D%2DCLEAR%2D%2D%3E"; var gBrowser; +// Are we testing web content loaded in a separate process? +var gBrowserIsRemote; // bool +var gBrowserMessageManager; var gCanvas1, gCanvas2; // gCurrentCanvas is non-null between InitCurrentCanvasWithSnapshot and the next // RecordResult. var gCurrentCanvas = null; var gURLs; // 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 @@ -91,41 +95,28 @@ var gTestResults = { KnownFail : 0, AssertionKnown: 0, Random : 0, Skip: 0, Slow: 0, }; var gTotalTests = 0; var gState; -// Plugin layers can be updated asynchronously, so to make sure that all -// layer surfaces have the right content, we need to listen for explicit -// "MozPaintWait" and "MozPaintWaitFinished" events that signal when it's OK -// to take snapshots. We cannot take a snapshot while the number of -// "MozPaintWait" events fired exceeds the number of "MozPaintWaitFinished" -// events fired. We count the number of such excess events here. When -// the counter reaches zero we call gExplicitPendingPaintsCompleteHook. -var gExplicitPendingPaintCount = 0; -var gExplicitPendingPaintsCompleteHook; var gCurrentURL; -var gFailureTimeout = null; -var gFailureReason; var gTestLog = []; var gServer; var gCount = 0; var gAssertionCount = 0; var gIOService; var gDebug; var gWindowUtils; -var gCurrentTestStartTime; var gSlowestTestTime = 0; var gSlowestTestURL; -var gClearingForAssertionCheck = false; var gDrawWindowFlags; 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 @@ -146,25 +137,29 @@ var gRunSlowTests = true; // whether we should skip caching canvases var gNoCanvasCache = false; var gRecycledCanvases = new Array(); // By default we just log to stdout var gDumpLog = dump; +// Only dump the sandbox once, because it doesn't depend on the +// manifest URL (yet!). +var gDumpedConditionSandbox = false; + function LogWarning(str) { gDumpLog("REFTEST INFO | " + str + "\n"); gTestLog.push(str); } function LogInfo(str) { - // gDumpLog("REFTEST INFO | " + str + "\n"); +// gDumpLog("REFTEST INFO | " + str + "\n"); gTestLog.push(str); } function FlushTestLog() { for (var i = 0; i < gTestLog.length; ++i) { gDumpLog("REFTEST INFO | Saved log: " + gTestLog[i] + "\n"); } @@ -197,40 +192,45 @@ function IDForEventTarget(event) { try { return "'" + event.target.getAttribute('id') + "'"; } catch (ex) { return "<unknown>"; } } -function PaintWaitListener(event) +function OnRefTestLoad() { - LogInfo("MozPaintWait received for ID " + IDForEventTarget(event)); - gExplicitPendingPaintCount++; + var prefs = Components.classes["@mozilla.org/preferences-service;1"]. + getService(Components.interfaces.nsIPrefBranch2); + try { + gBrowserIsRemote = prefs.getBoolPref("browser.tabs.remote"); + } catch (e) { + gBrowserIsRemote = false; + } + + gBrowser = document.createElementNS(XUL_NS, "xul:browser"); + gBrowser.setAttribute("id", "browser"); + gBrowser.setAttribute("type", "content-primary"); + gBrowser.setAttribute("remote", gBrowserIsRemote ? "true" : "false"); + // Make sure the browser element is exactly 800x1000, no matter + // what size our window is + gBrowser.setAttribute("style", "min-width: 800px; min-height: 1000px; max-width: 800px; max-height: 1000px"); + + document.getElementById("reftest-window").appendChild(gBrowser); + + gBrowserMessageManager = gBrowser.QueryInterface(CI.nsIFrameLoaderOwner) + .frameLoader.messageManager; + // The content script waits for the initial onload, then notifies + // us. + RegisterMessageListenersAndLoadContentScript(); } -function PaintWaitFinishedListener(event) +function InitAndStartRefTests() { - LogInfo("MozPaintWaitFinished received for ID " + IDForEventTarget(event)); - gExplicitPendingPaintCount--; - if (gExplicitPendingPaintCount < 0) { - LogWarning("Underrun in gExplicitPendingPaintCount\n"); - gExplicitPendingPaintCount = 0; - } - if (gExplicitPendingPaintCount == 0 && - gExplicitPendingPaintsCompleteHook) { - gExplicitPendingPaintsCompleteHook(); - } -} - -function OnRefTestLoad() -{ - gBrowser = document.getElementById("browser"); - /* set the gLoadTimeout */ try { var prefs = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch2); gLoadTimeout = prefs.getIntPref("reftest.timeout"); logFile = prefs.getCharPref("reftest.logFile"); if (logFile) { try { @@ -255,18 +255,16 @@ function OnRefTestLoad() gTotalChunks = prefs.getIntPref("reftest.totalChunks"); gThisChunk = prefs.getIntPref("reftest.thisChunk"); } catch(e) { gTotalChunks = 0; gThisChunk = 0; } - gBrowser.addEventListener("load", OnDocumentLoad, true); - try { gWindowUtils = window.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIDOMWindowUtils); if (gWindowUtils && !gWindowUtils.compareCanvases) gWindowUtils = null; } catch (e) { gWindowUtils = null; } @@ -289,20 +287,16 @@ function OnRefTestLoad() ++gTestResults.Exception; gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); DoneTests(); } // Focus the content browser gBrowser.focus(); - // Connect to async rendering notifications - gBrowser.addEventListener("MozPaintWait", PaintWaitListener, true); - gBrowser.addEventListener("MozPaintWaitFinished", PaintWaitFinishedListener, true); - StartTests(); } function StartHTTPServer() { gServer.registerContentType("sjs", "sjs"); // We want to try different ports in case the port we want // is being used. @@ -354,17 +348,16 @@ function StartTests() ++gTestResults.Exception; gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); DoneTests(); } } function OnRefTestUnload() { - gBrowser.removeEventListener("load", OnDocumentLoad, true); MozillaFileLogger.close(); } // Read all available data from an input stream and return it // as a string. function getStreamContent(inputStream) { var streamBuf = ""; @@ -392,17 +385,17 @@ function BuildConditionSandbox(aURL) { try { sandbox.xulRuntime.XPCOMABI = xr.XPCOMABI; } catch(e) { sandbox.xulRuntime.XPCOMABI = ""; } try { // nsIGfxInfo is currently only implemented on Windows - sandbox.d2d = CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo).D2DEnabled; + sandbox.d2d = (NS_GFXINFO_CONTRACTID in CC) && CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo).D2DEnabled; } catch(e) { sandbox.d2d = false; } if (gWindowUtils && gWindowUtils.layerManagerType != "Basic") sandbox.layersGPUAccelerated = true; else sandbox.layersGPUAccelerated = false; @@ -487,18 +480,25 @@ function BuildConditionSandbox(aURL) { } else { testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled"); } return testPluginIsOOP; }; - gDumpLog("REFTEST INFO | Dumping JSON representation of sandbox \n"); - gDumpLog("REFTEST INFO | " + JSON.stringify(sandbox) + " \n"); + // Tests shouldn't care about this except for when they need to + // crash the content process + sandbox.browserIsRemote = gBrowserIsRemote; + + if (!gDumpedConditionSandbox) { + dump("REFTEST INFO | Dumping JSON representation of sandbox \n"); + dump("REFTEST INFO | " + JSON.stringify(sandbox) + " \n"); + gDumpedConditionSandbox = true; + } return sandbox; } function ReadTopManifest(aFileURL) { gURLs = new Array(); var url = gIOService.newURI(aFileURL, null, null); @@ -550,29 +550,32 @@ function ReadManifest(aURL) urlprefix = items[1]; continue; } var expected_status = EXPECTED_PASS; var allow_silent_fail = false; var minAsserts = 0; var maxAsserts = 0; + var needs_focus = false; var slow = false; - while (items[0].match(/^(fails|random|skip|asserts|slow|silentfail)/)) { + while (items[0].match(/^(fails|needs-focus|random|skip|asserts|slow|silentfail)/)) { var item = items.shift(); var stat; var cond; var m = item.match(/^(fails|random|skip|silentfail)-if(\(.*\))$/); if (m) { stat = m[1]; // Note: m[2] contains the parentheses, and we want them. cond = Components.utils.evalInSandbox(m[2], sandbox); } else if (item.match(/^(fails|random|skip)$/)) { stat = item; cond = true; + } else if (item == "needs-focus") { + needs_focus = true; } 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)) { @@ -660,16 +663,17 @@ function ReadManifest(aURL) secMan.checkLoadURI(aURL, testURI, CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); gURLs.push( { type: TYPE_LOAD, expected: expected_status, allowSilentFail: allow_silent_fail, prettyPath: prettyPath, minAsserts: minAsserts, maxAsserts: maxAsserts, + needsFocus: needs_focus, slow: slow, url1: testURI, url2: null } ); } else if (items[0] == TYPE_SCRIPT) { if (items.length != 2) throw "Error 4 in manifest file " + aURL.spec + " line " + lineNo; var [testURI] = runHttp ? ServeFiles(aURL, httpDepth, @@ -681,16 +685,17 @@ function ReadManifest(aURL) secMan.checkLoadURI(aURL, testURI, CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); gURLs.push( { type: TYPE_SCRIPT, expected: expected_status, allowSilentFail: allow_silent_fail, prettyPath: prettyPath, minAsserts: minAsserts, maxAsserts: maxAsserts, + needsFocus: needs_focus, slow: slow, url1: testURI, url2: null } ); } else if (items[0] == TYPE_REFTEST_EQUAL || items[0] == TYPE_REFTEST_NOTEQUAL) { if (items.length != 3) throw "Error 5 in manifest file " + aURL.spec + " line " + lineNo; var [testURI, refURI] = runHttp ? ServeFiles(aURL, httpDepth, @@ -705,16 +710,17 @@ function ReadManifest(aURL) secMan.checkLoadURI(aURL, refURI, CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); gURLs.push( { type: items[0], expected: expected_status, allowSilentFail: allow_silent_fail, prettyPath: prettyPath, minAsserts: minAsserts, maxAsserts: maxAsserts, + needsFocus: needs_focus, slow: slow, url1: testURI, url2: refURI } ); } else { throw "Error 6 in manifest file " + aURL.spec + " line " + lineNo; } } } @@ -782,27 +788,51 @@ function ServeFiles(manifestURL, depth, CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); return testURI; } return files.map(FileToURI); } +// Return true iff this window is focused when this function returns. +function Focus() +{ + // FIXME/bug 583976: focus doesn't yet work with out-of-process + // content. + if (gBrowserIsRemote) { + return false; + } + + // FIXME/bug 623625: determine if the window is focused and/or try + // to acquire focus if it's not. + // + // NB: we can't add anything here that would return false on + // tinderbox, otherwise we could lose testing coverage due to + // problems on the test machines. We might want a require-focus + // mode, defaulting to false for developers, but that's true on + // tinderbox. + return true; +} + function StartCurrentTest() { gTestLog = []; // make sure we don't run tests that are expected to kill the browser while (gURLs.length > 0) { var test = gURLs[0]; if (test.expected == EXPECTED_DEATH) { ++gTestResults.Skip; gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + " | (SKIP)\n"); gURLs.shift(); + } else if (test.needsFocus && !Focus()) { + ++gTestResults.Skip; + gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + " | (SKIPPED; COULDN'T GET FOCUS)\n"); + gURLs.shift(); } else if (test.slow && !gRunSlowTests) { ++gTestResults.Slow; gDumpLog("REFTEST TEST-KNOWN-SLOW | " + test.url1.spec + " | (SLOW)\n"); gURLs.shift(); } else { break; } } @@ -815,46 +845,35 @@ function StartCurrentTest() document.title = "reftest: " + currentTest + " / " + gTotalTests + " (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)"; StartCurrentURI(1); } } function StartCurrentURI(aState) { - gCurrentTestStartTime = Date.now(); - if (gFailureTimeout != null) { - gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + - "| program error managing timeouts\n"); - ++gTestResults.Exception; - } - gFailureTimeout = setTimeout(LoadFailed, gLoadTimeout); - gFailureReason = "timed out waiting for onload to fire"; - gState = aState; gCurrentURL = gURLs[0]["url" + aState].spec; - // Reset gExplicitPendingPaintCount in case there was a timeout or - // the count is out of sync for some other reason - if (gExplicitPendingPaintCount != 0) { - LogWarning("Resetting gExplicitPendingPaintCount to zero (currently " + - gExplicitPendingPaintCount + "\n"); - gExplicitPendingPaintCount = 0; - } if (gURICanvases[gCurrentURL] && (gURLs[0].type == TYPE_REFTEST_EQUAL || gURLs[0].type == TYPE_REFTEST_NOTEQUAL) && gURLs[0].maxAsserts == 0) { // Pretend the document loaded --- RecordResult will notice // there's already a canvas for this URL setTimeout(RecordResult, 0); } else { gDumpLog("REFTEST TEST-START | " + gCurrentURL + "\n"); LogInfo("START " + gCurrentURL); - gBrowser.loadURI(gCurrentURL); + var type = gURLs[0].type + if (TYPE_SCRIPT == type) { + SendLoadScriptTest(gCurrentURL, gLoadTimeout); + } else { + SendLoadTest(type, gCurrentURL, gLoadTimeout); + } } } function DoneTests() { gDumpLog("REFTEST FINISHED: Slowest test took " + gSlowestTestTime + "ms (" + gSlowestTestURL + ")\n"); @@ -890,340 +909,16 @@ function DoneTests() goQuitApplication(); } if (gServer) gServer.stop(onStopped); else onStopped(); } -function setupZoom(contentRootElement) { - if (!contentRootElement || !contentRootElement.hasAttribute('reftest-zoom')) - return; - gBrowser.markupDocumentViewer.fullZoom = - contentRootElement.getAttribute('reftest-zoom'); -} - -function resetZoom() { - gBrowser.markupDocumentViewer.fullZoom = 1.0; -} - -function doPrintMode(contentRootElement) { - // use getAttribute because className works differently in HTML and SVG - return contentRootElement && - contentRootElement.hasAttribute('class') && - contentRootElement.getAttribute('class').split(/\s+/) - .indexOf("reftest-print") != -1; -} - -function setupPrintMode() { - var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] - .getService(Components.interfaces.nsIPrintSettingsService); - var ps = PSSVC.newPrintSettings; - ps.paperWidth = 5; - ps.paperHeight = 3; - - // Override any os-specific unwriteable margins - ps.unwriteableMarginTop = 0; - ps.unwriteableMarginLeft = 0; - ps.unwriteableMarginBottom = 0; - ps.unwriteableMarginRight = 0; - - ps.headerStrLeft = ""; - ps.headerStrCenter = ""; - ps.headerStrRight = ""; - ps.footerStrLeft = ""; - ps.footerStrCenter = ""; - ps.footerStrRight = ""; - gBrowser.docShell.contentViewer.setPageMode(true, ps); -} - -function shouldWaitForExplicitPaintWaiters() { - return gExplicitPendingPaintCount > 0; -} - -function shouldWaitForPendingPaints() { - // if gCurrentCanvas is null, we're not taking snapshots so there is - // no need to wait for pending paints to be flushed. - return gCurrentCanvas && gWindowUtils.isMozAfterPaintPending; -} - -function shouldWaitForReftestWaitRemoval(contentRootElement) { - // use getAttribute because className works differently in HTML and SVG - return contentRootElement && - contentRootElement.hasAttribute('class') && - contentRootElement.getAttribute('class').split(/\s+/) - .indexOf("reftest-wait") != -1; -} - -// Initial state. When the document has loaded and all MozAfterPaint events and -// all explicit paint waits are flushed, we can fire the MozReftestInvalidate -// event and move to the next state. -const STATE_WAITING_TO_FIRE_INVALIDATE_EVENT = 0; -// When reftest-wait has been removed from the root element, we can move to the -// next state. -const STATE_WAITING_FOR_REFTEST_WAIT_REMOVAL = 1; -// When all MozAfterPaint events and all explicit paint waits are flushed, we're -// done and can move to the COMPLETED state. -const STATE_WAITING_TO_FINISH = 2; -const STATE_COMPLETED = 3; - -function WaitForTestEnd(contentRootElement, inPrintMode) { - var stopAfterPaintReceived = false; - var state = STATE_WAITING_TO_FIRE_INVALIDATE_EVENT; - - function FlushRendering() { - var anyPendingPaintsGeneratedInDescendants = false; - - function flushWindow(win) { - var utils = win.QueryInterface(CI.nsIInterfaceRequestor) - .getInterface(CI.nsIDOMWindowUtils); - var afterPaintWasPending = utils.isMozAfterPaintPending; - - try { - // Flush pending restyles and reflows for this window - win.document.documentElement.getBoundingClientRect(); - } catch (e) { - LogWarning("flushWindow failed: " + e + "\n"); - } - - if (!afterPaintWasPending && utils.isMozAfterPaintPending) { - LogInfo("FlushRendering generated paint for window " + win.location.href); - anyPendingPaintsGeneratedInDescendants = true; - } - - for (var i = 0; i < win.frames.length; ++i) { - flushWindow(win.frames[i]); - } - } - - flushWindow(gBrowser.contentWindow); - - if (anyPendingPaintsGeneratedInDescendants && - !gWindowUtils.isMozAfterPaintPending) { - LogWarning("Internal error: descendant frame generated a MozAfterPaint event, but the root document doesn't have one!"); - } - } - - function AfterPaintListener(event) { - LogInfo("AfterPaintListener in " + event.target.document.location.href); - if (event.target.document != document) { - // ignore paint events for subframes or old documents in the window. - // Invalidation in subframes will cause invalidation in the toplevel document anyway. - return; - } - UpdateCurrentCanvasForEvent(event); - // These events are fired immediately after a paint. Don't - // confuse ourselves by firing synchronously if we triggered the - // paint ourselves. - setTimeout(MakeProgress, 0); - } - - function AttrModifiedListener() { - LogInfo("AttrModifiedListener fired"); - // Wait for the next return-to-event-loop before continuing --- for - // example, the attribute may have been modified in an subdocument's - // load event handler, in which case we need load event processing - // to complete and unsuppress painting before we check isMozAfterPaintPending. - setTimeout(MakeProgress, 0); - } - - function ExplicitPaintsCompleteListener() { - LogInfo("ExplicitPaintsCompleteListener fired"); - // Since this can fire while painting, don't confuse ourselves by - // firing synchronously. It's fine to do this asynchronously. - setTimeout(MakeProgress, 0); - } - - function RemoveListeners() { - // OK, we can end the test now. - window.removeEventListener("MozAfterPaint", AfterPaintListener, false); - if (contentRootElement) { - contentRootElement.removeEventListener("DOMAttrModified", AttrModifiedListener, false); - } - gExplicitPendingPaintsCompleteHook = null; - gTimeoutHook = null; - // Make sure we're in the COMPLETED state just in case - // (this may be called via the test-timeout hook) - state = STATE_COMPLETED; - } - - // Everything that could cause shouldWaitForXXX() to - // change from returning true to returning false is monitored via some kind - // of event listener which eventually calls this function. - function MakeProgress() { - if (state >= STATE_COMPLETED) { - LogInfo("MakeProgress: STATE_COMPLETED"); - return; - } - - FlushRendering(); - - switch (state) { - case STATE_WAITING_TO_FIRE_INVALIDATE_EVENT: { - LogInfo("MakeProgress: STATE_WAITING_TO_FIRE_INVALIDATE_EVENT"); - if (shouldWaitForExplicitPaintWaiters() || shouldWaitForPendingPaints()) { - gFailureReason = "timed out waiting for pending paint count to reach zero"; - if (shouldWaitForExplicitPaintWaiters()) { - gFailureReason += " (waiting for MozPaintWaitFinished)"; - LogInfo("MakeProgress: waiting for MozPaintWaitFinished"); - } - if (shouldWaitForPendingPaints()) { - gFailureReason += " (waiting for MozAfterPaint)"; - LogInfo("MakeProgress: waiting for MozAfterPaint"); - } - return; - } - - state = STATE_WAITING_FOR_REFTEST_WAIT_REMOVAL; - var hasReftestWait = shouldWaitForReftestWaitRemoval(contentRootElement); - // Notify the test document that now is a good time to test some invalidation - if (contentRootElement) { - var notification = document.createEvent("Events"); - notification.initEvent("MozReftestInvalidate", true, false); - contentRootElement.dispatchEvent(notification); - } - if (hasReftestWait && !shouldWaitForReftestWaitRemoval(contentRootElement)) { - // MozReftestInvalidate handler removed reftest-wait. - // We expect something to have been invalidated... - FlushRendering(); - if (!shouldWaitForPendingPaints() && !shouldWaitForExplicitPaintWaiters()) { - LogWarning("MozInvalidateEvent didn't invalidate"); - } - } - // Try next state - MakeProgress(); - return; - } - - case STATE_WAITING_FOR_REFTEST_WAIT_REMOVAL: - LogInfo("MakeProgress: STATE_WAITING_FOR_REFTEST_WAIT_REMOVAL"); - if (shouldWaitForReftestWaitRemoval(contentRootElement)) { - gFailureReason = "timed out waiting for reftest-wait to be removed"; - LogInfo("MakeProgress: waiting for reftest-wait to be removed"); - return; - } - state = STATE_WAITING_TO_FINISH; - if (!inPrintMode && doPrintMode(contentRootElement)) { - LogInfo("MakeProgress: setting up print mode"); - setupPrintMode(); - } - // Try next state - MakeProgress(); - return; - - case STATE_WAITING_TO_FINISH: - LogInfo("MakeProgress: STATE_WAITING_TO_FINISH"); - if (shouldWaitForExplicitPaintWaiters() || shouldWaitForPendingPaints()) { - gFailureReason = "timed out waiting for pending paint count to " + - "reach zero (after reftest-wait removed and switch to print mode)"; - if (shouldWaitForExplicitPaintWaiters()) { - gFailureReason += " (waiting for MozPaintWaitFinished)"; - LogInfo("MakeProgress: waiting for MozPaintWaitFinished"); - } - if (shouldWaitForPendingPaints()) { - gFailureReason += " (waiting for MozAfterPaint)"; - LogInfo("MakeProgress: waiting for MozAfterPaint"); - } - return; - } - LogInfo("MakeProgress: Completed"); - state = STATE_COMPLETED; - gFailureReason = "timed out while taking snapshot (bug in harness?)"; - RemoveListeners(); - setTimeout(RecordResult, 0); - return; - } - } - - LogInfo("WaitForTestEnd: Adding listeners"); - window.addEventListener("MozAfterPaint", AfterPaintListener, false); - // If contentRootElement is null then shouldWaitForReftestWaitRemoval will - // always return false so we don't need a listener anyway - if (contentRootElement) { - contentRootElement.addEventListener("DOMAttrModified", AttrModifiedListener, false); - } - gExplicitPendingPaintsCompleteHook = ExplicitPaintsCompleteListener; - gTimeoutHook = RemoveListeners; - - // Take a full snapshot now that all our listeners are set up. This - // ensures it's impossible for us to miss updates between taking the snapshot - // and adding our listeners. - InitCurrentCanvasWithSnapshot(); - MakeProgress(); -} - -function OnDocumentLoad(event) -{ - var currentDoc = gBrowser.contentDocument; - if (event.target != currentDoc) - // Ignore load events for subframes. - return; - - if (gClearingForAssertionCheck && - currentDoc.location.href == BLANK_URL_FOR_CLEARING) { - DoAssertionCheck(); - return; - } - - if (currentDoc.location.href != gCurrentURL) { - LogInfo("OnDocumentLoad fired for previous document"); - // Ignore load events for previous documents. - return; - } - - var contentRootElement = currentDoc ? currentDoc.documentElement : null; - setupZoom(contentRootElement); - var inPrintMode = false; - - function AfterOnLoadScripts() { - // Take a snapshot now. We need to do this before we check whether - // we should wait, since this might trigger dispatching of - // MozPaintWait events and make shouldWaitForExplicitPaintWaiters() true - // below. - var painted = InitCurrentCanvasWithSnapshot(); - - if (shouldWaitForExplicitPaintWaiters() || - (!inPrintMode && doPrintMode(contentRootElement)) || - // If we didn't force a paint above, in - // InitCurrentCanvasWithSnapshot, so we should wait for a - // paint before we consider them done. - !painted) { - LogInfo("AfterOnLoadScripts belatedly entering WaitForTestEnd"); - // Go into reftest-wait mode belatedly. - WaitForTestEnd(contentRootElement, inPrintMode); - } else { - RecordResult(); - } - } - - if (shouldWaitForReftestWaitRemoval(contentRootElement) || - shouldWaitForExplicitPaintWaiters()) { - // Go into reftest-wait mode immediately after painting has been - // unsuppressed, after the onload event has finished dispatching. - gFailureReason = "timed out waiting for test to complete (trying to get into WaitForTestEnd)"; - LogInfo("OnDocumentLoad triggering WaitForTestEnd"); - setTimeout(WaitForTestEnd, 0, contentRootElement, inPrintMode); - } else { - if (doPrintMode(contentRootElement)) { - LogInfo("OnDocumentLoad setting up print mode"); - setupPrintMode(); - inPrintMode = true; - } - - // Since we can't use a bubbling-phase load listener from chrome, - // this is a capturing phase listener. So do setTimeout twice, the - // first to get us after the onload has fired in the content, and - // the second to get us after any setTimeout(foo, 0) in the content. - gFailureReason = "timed out waiting for test to complete (waiting for onload scripts to complete)"; - LogInfo("OnDocumentLoad triggering AfterOnLoadScripts"); - setTimeout(setTimeout, 0, AfterOnLoadScripts, 0); - } -} - function UpdateCanvasCache(url, canvas) { var spec = url.spec; --gURIUseCounts[spec]; if (gNoCanvasCache || gURIUseCounts[spec] == 0) { ReleaseCanvas(canvas); @@ -1247,16 +942,19 @@ function DoDrawWindow(ctx, x, y, w, h) if (0 <= testRect.left && 0 <= testRect.top && window.innerWidth >= testRect.right && window.innerHeight >= testRect.bottom) { // 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; + } else if (gBrowserIsRemote) { + gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | can't drawWindow remote content\n"); + ++gTestResults.Exception; } 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"; @@ -1273,72 +971,66 @@ function DoDrawWindow(ctx, x, y, w, h) LogInfo("DoDrawWindow " + x + "," + y + "," + w + "," + h); ctx.drawWindow(window, x, y, w, h, "rgb(255,255,255)", gDrawWindowFlags); } function InitCurrentCanvasWithSnapshot() { + LogInfo("Initializing canvas snapshot"); + if (gURLs[0].type == TYPE_LOAD || gURLs[0].type == TYPE_SCRIPT) { // We don't want to snapshot this kind of test return false; } if (!gCurrentCanvas) { gCurrentCanvas = AllocateCanvas(); } var ctx = gCurrentCanvas.getContext("2d"); DoDrawWindow(ctx, 0, 0, gCurrentCanvas.width, gCurrentCanvas.height); return true; } -function roundTo(x, fraction) +function UpdateCurrentCanvasForInvalidation(rects) { - return Math.round(x/fraction)*fraction; -} + LogInfo("Updating canvas for invalidation"); -function UpdateCurrentCanvasForEvent(event) -{ - if (!gCurrentCanvas) + if (!gCurrentCanvas) { return; + } var ctx = gCurrentCanvas.getContext("2d"); - var rectList = event.clientRects; - for (var i = 0; i < rectList.length; ++i) { - var r = rectList[i]; + for (var i = 0; i < rects.length; ++i) { + var r = rects[i]; // 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); ctx.save(); ctx.translate(left, top); DoDrawWindow(ctx, left, top, right - left, bottom - top); ctx.restore(); } } -function RecordResult() +function RecordResult(testRunTime, errorMsg, scriptResults) { LogInfo("RecordResult fired"); // Keep track of which test was slowest, and how long it took. - var currentTestRunTime = Date.now() - gCurrentTestStartTime; - if (currentTestRunTime > gSlowestTestTime) { - gSlowestTestTime = currentTestRunTime; + if (testRunTime > gSlowestTestTime) { + gSlowestTestTime = testRunTime; gSlowestTestURL = gCurrentURL; } - clearTimeout(gFailureTimeout); - gFailureReason = null; - gFailureTimeout = null; - // Not 'const ...' because of 'EXPECTED_*' value dependency. var outputs = {}; const randomMsg = "(EXPECTED RANDOM)"; outputs[EXPECTED_PASS] = { true: {s: "TEST-PASS" , n: "Pass"}, false: {s: "TEST-UNEXPECTED-FAIL" , n: "UnexpectedFail"} }; outputs[EXPECTED_FAIL] = { @@ -1354,74 +1046,57 @@ function RecordResult() if (gURLs[0].type == TYPE_LOAD) { ++gTestResults.LoadOnly; gDumpLog("REFTEST TEST-PASS | " + gURLs[0].prettyPath + " | (LOAD ONLY)\n"); gCurrentCanvas = null; FinishTestItem(); return; } if (gURLs[0].type == TYPE_SCRIPT) { - var missing_msg = false; - var testwindow = gBrowser.contentWindow; - expected = gURLs[0].expected; + var expected = gURLs[0].expected; - if (testwindow.wrappedJSObject) - testwindow = testwindow.wrappedJSObject; - - var testcases; - - if (!testwindow.getTestCases || typeof testwindow.getTestCases != "function") { + if (errorMsg) { // Force an unexpected failure to alert the test author to fix the test. expected = EXPECTED_PASS; - missing_msg = "test must provide a function getTestCases(). (SCRIPT)\n"; - } - else if (!(testcases = testwindow.getTestCases())) { - // Force an unexpected failure to alert the test author to fix the test. - expected = EXPECTED_PASS; - missing_msg = "test's getTestCases() must return an Array-like Object. (SCRIPT)\n"; - } - else if (testcases.length == 0) { - // 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) - missing_msg = "No test results reported. (SCRIPT)\n"; - else - gDumpLog("REFTEST INFO | An expected silent failure occurred \n"); + } else if (scriptResults.length == 0) { + // 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 + gDumpLog("REFTEST INFO | An expected silent failure occurred \n"); } - if (missing_msg) { + if (errorMsg) { output = outputs[expected][false]; ++gTestResults[output.n]; var result = "REFTEST " + output.s + " | " + gURLs[0].prettyPath + " | " + // the URL being tested - missing_msg; + errorMsg; gDumpLog(result); FinishTestItem(); return; } - var results = testcases.map(function(test) { - return { passed: test.testPassed(), description: test.testDescription()}; - }); - var anyFailed = results.some(function(result) { return !result.passed; }); + var anyFailed = scriptResults.some(function(result) { return !result.passed; }); 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; - results.forEach(function(result) { + scriptResults.forEach(function(result) { var output = outputPair[result.passed]; ++gTestResults[output.n]; result = "REFTEST " + output.s + " | " + gURLs[0].prettyPath + " | " + // the URL being tested result.description + " item " + (++index) + "\n"; gDumpLog(result); }); @@ -1432,24 +1107,28 @@ function RecordResult() FinishTestItem(); return; } if (gURICanvases[gCurrentURL]) { gCurrentCanvas = gURICanvases[gCurrentURL]; } + if (gCurrentCanvas == null) { + gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | program error managing snapshots\n"); + ++gTestResults.Exception; + } if (gState == 1) { gCanvas1 = gCurrentCanvas; } else { gCanvas2 = gCurrentCanvas; } gCurrentCanvas = null; - resetZoom(); + SendResetZoom(); switch (gState) { case 1: // First document has been loaded. // Proceed to load the second document. StartCurrentURI(2); break; @@ -1513,46 +1192,47 @@ function RecordResult() FinishTestItem(); break; default: throw "Unexpected state."; } } -function LoadFailed() +function LoadFailed(why) { - if (gTimeoutHook) { - gTimeoutHook(); - } - gFailureTimeout = null; ++gTestResults.FailedLoad; gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + - gURLs[0]["url" + gState].spec + " | " + gFailureReason + "\n"); + gURLs[0]["url" + gState].spec + " | " + why + "\n"); FlushTestLog(); FinishTestItem(); } function FinishTestItem() { // Replace document with BLANK_URL_FOR_CLEARING in case there are // assertions when unloading. gDumpLog("REFTEST INFO | Loading a blank page\n"); - gClearingForAssertionCheck = true; - gBrowser.loadURI(BLANK_URL_FOR_CLEARING); + // After clearing, content will notify us of the assertion count + // and tests will continue. + SendClear(); } -function DoAssertionCheck() +function DoAssertionCheck(numAsserts) { - gClearingForAssertionCheck = false; + if (gDebug.isDebugBuild) { + if (gBrowserIsRemote) { + // Count chrome-process asserts too when content is out of + // process. + var newAssertionCount = gDebug.assertionCount; + var numLocalAsserts = newAssertionCount - gAssertionCount; + gAssertionCount = newAssertionCount; - if (gDebug.isDebugBuild) { - var newAssertionCount = gDebug.assertionCount; - var numAsserts = newAssertionCount - gAssertionCount; - gAssertionCount = newAssertionCount; + numAsserts += numLocalAsserts; + } var minAsserts = gURLs[0].minAsserts; var maxAsserts = gURLs[0].maxAsserts; var expectedAssertions = "expected " + minAsserts; if (minAsserts != maxAsserts) { expectedAssertions += " to " + maxAsserts; } @@ -1575,8 +1255,130 @@ function DoAssertionCheck() expectedAssertions + "\n"); } } // And start the next test. gURLs.shift(); StartCurrentTest(); } + + +function RegisterMessageListenersAndLoadContentScript() +{ + gBrowserMessageManager.addMessageListener( + "reftest:AssertionCount", + function (m) { RecvAssertionCount(m.json.count); } + ); + gBrowserMessageManager.addMessageListener( + "reftest:ContentReady", + function (m) { return RecvContentReady() } + ); + gBrowserMessageManager.addMessageListener( + "reftest:Exception", + function (m) { RecvException(m.json.what) } + ); + gBrowserMessageManager.addMessageListener( + "reftest:FailedLoad", + function (m) { RecvFailedLoad(m.json.why); } + ); + 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); } + ); + gBrowserMessageManager.addMessageListener( + "reftest:TestDone", + function (m) { RecvTestDone(m.json.runtimeMs); } + ); + gBrowserMessageManager.addMessageListener( + "reftest:UpdateCanvasForInvalidation", + function (m) { RecvUpdateCanvasForInvalidation(m.json.rects); } + ); + + gBrowserMessageManager.loadFrameScript("chrome://reftest/content/reftest-content.js", true); +} + +function RecvAssertionCount(count) +{ + DoAssertionCheck(count); +} + +function RecvContentReady() +{ + InitAndStartRefTests(); + return { remote: gBrowserIsRemote }; +} + +function RecvException(what) +{ + gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | "+ what +"\n"); + ++gTestResults.Exception; +} + +function RecvFailedLoad(why) +{ + LoadFailed(why); +} + +function RecvInitCanvasWithSnapshot() +{ + var painted = InitCurrentCanvasWithSnapshot(); + return { painted: painted }; +} + +function RecvLog(type, msg) +{ + msg = "[CONTENT] "+ msg; + if (type == "info") { + LogInfo(msg); + } else if (type == "warning") { + LogWarning(msg); + } else { + gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | unknown log type "+ type +"\n"); + ++gTestResults.Exception; + } +} + +function RecvScriptResults(runtimeMs, error, results) +{ + RecordResult(runtimeMs, error, results); +} + +function RecvTestDone(runtimeMs) +{ + RecordResult(runtimeMs, '', [ ]); +} + +function RecvUpdateCanvasForInvalidation(rects) +{ + UpdateCurrentCanvasForInvalidation(rects); +} + +function SendClear() +{ + gBrowserMessageManager.sendAsyncMessage("reftest:Clear"); +} + +function SendLoadScriptTest(uri, timeout) +{ + gBrowserMessageManager.sendAsyncMessage("reftest:LoadScriptTest", + { uri: uri, timeout: timeout }); +} + +function SendLoadTest(type, uri, timeout) +{ + gBrowserMessageManager.sendAsyncMessage("reftest:LoadTest", + { type: type, uri: uri, timeout: timeout } + ); +} + +function SendResetZoom() +{ + gBrowserMessageManager.sendAsyncMessage("reftest:ResetZoom"); +}
--- a/layout/tools/reftest/reftest.xul +++ b/layout/tools/reftest/reftest.xul @@ -47,12 +47,10 @@ hidechrome="true" onload="OnRefTestLoad();" onunload="OnRefTestUnload();" style="background:white; overflow:hidden" > <script type="application/ecmascript" src="quit.js" /> <script type="application/ecmascript" src="reftest.js" /> <script type="application/ecmascript" src="MozillaFileLogger.js" /> - <!-- Make sure the browser element is exactly 800x1000, no matter what size our window is --> - <browser id="browser" type="content-primary" - style="min-width: 800px; min-height: 1000px; max-width: 800px; max-height: 1000px" /> + <!-- The reftest browser element is dynamically created, here --> </window>
--- a/modules/plugin/test/crashtests/crashtests.list +++ b/modules/plugin/test/crashtests/crashtests.list @@ -1,7 +1,11 @@ load 41276-1.html load 48856-1.html load 110650-1.html -skip-if(!haveTestPlugin) skip-if(cocoaWidget) script 539897-1.html -skip-if(!haveTestPlugin) script 540114-1.html +skip-if(browserIsRemote||!haveTestPlugin||cocoaWidget) script 539897-1.html # browserIsRemote is bug XXXXXX +skip-if(browserIsRemote||!haveTestPlugin) script 540114-1.html # browserIsRemote is bug XXXXXX load 570884.html -skip-if(!haveTestPlugin||http.platform!="X11"||!testPluginIsOOP()) load 598862.html +# This test relies on the reading of screenX/Y forcing a round trip to +# the X server, which is a bad assumption for <browser remote>. +# Plugin arch is going to change anyway with OOP content so skipping +# this test for now is OK. +skip-if(browserIsRemote||!haveTestPlugin||http.platform!="X11"||!testPluginIsOOP()) load 598862.html
--- a/security/manager/ssl/crashtests/crashtests.list +++ b/security/manager/ssl/crashtests/crashtests.list @@ -1,2 +1,2 @@ -load 327524-1.html -load 398665-1.html +asserts-if(browserIsRemote,1) load 327524-1.html # bug 582297 +asserts-if(browserIsRemote,1) load 398665-1.html # bug 582297
--- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -107,26 +107,55 @@ else $(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled=true --test-path=modules/plugin/test endif $(CHECK_TEST_ERROR) # Usage: |make [EXTRA_TEST_ARGS=...] *test|. RUN_REFTEST = rm -f ./$@.log && $(PYTHON) _tests/reftest/runreftest.py \ $(SYMBOLS_PATH) $(EXTRA_TEST_ARGS) $(1) | tee ./$@.log +ifeq ($(OS_ARCH),WINNT) #{ +# GPU-rendered shadow layers are unsupported here +OOP_CONTENT = --setpref=browser.tabs.remote=true --setpref=layers.acceleration.disabled=true +GPU_RENDERING = +else +OOP_CONTENT = --setpref=browser.tabs.remote=true +GPU_RENDERING = --setpref=layers.acceleration.force-enabled=true +endif #} + reftest: TEST_PATH?=layout/reftests/reftest.list reftest: $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH)) $(CHECK_TEST_ERROR) +reftest-ipc: TEST_PATH?=layout/reftests/reftest.list +reftest-ipc: + $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH) $(OOP_CONTENT)) + $(CHECK_TEST_ERROR) + +reftest-ipc-gpu: TEST_PATH?=layout/reftests/reftest.list +reftest-ipc-gpu: + $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH) $(OOP_CONTENT) $(GPU_RENDERING)) + $(CHECK_TEST_ERROR) + crashtest: TEST_PATH?=testing/crashtest/crashtests.list crashtest: $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH)) $(CHECK_TEST_ERROR) +crashtest-ipc: TEST_PATH?=testing/crashtest/crashtests.list +crashtest-ipc: + $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH) $(OOP_CONTENT)) + $(CHECK_TEST_ERROR) + +crashtest-ipc-gpu: TEST_PATH?=testing/crashtest/crashtests.list +crashtest-ipc-gpu: + $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH) $(OOP_CONTENT) $(GPU_RENDERING)) + $(CHECK_TEST_ERROR) + jstestbrowser: TEST_PATH?=js/src/tests/jstests.list jstestbrowser: $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH) --extra-profile-file=$(topsrcdir)/js/src/tests/user.js) $(CHECK_TEST_ERROR) GARBAGE += $(addsuffix .log,$(MOCHITESTS) reftest crashtest jstestbrowser) # Execute all xpcshell tests in the directories listed in the manifest.