3 # Any copyright is dedicated to the Public Domain.
4 # http://creativecommons.org/publicdomain/zero/1.0/
17 from mozlog
import structured
18 from runxpcshelltests
import XPCShellTests
20 TEST_PASS_STRING
= "TEST-PASS"
21 TEST_FAIL_STRING
= "TEST-UNEXPECTED-FAIL"
23 SIMPLE_PASSING_TEST
= "function run_test() { Assert.ok(true); }"
24 SIMPLE_FAILING_TEST
= "function run_test() { Assert.ok(false); }"
25 SIMPLE_PREFCHECK_TEST
= """
27 Assert.ok(Services.prefs.getBoolPref("fake.pref.to.test"));
31 SIMPLE_UNCAUGHT_REJECTION_TEST
= """
33 Promise.reject(new Error("Test rejection."));
39 function run_test() { run_next_test(); }
41 add_test(function test_simple() {
47 ADD_TEST_FAILING
= """
48 function run_test() { run_next_test(); }
50 add_test(function test_failing() {
56 ADD_TEST_UNCAUGHT_REJECTION
= """
57 function run_test() { run_next_test(); }
59 add_test(function test_uncaught_rejection() {
60 Promise.reject(new Error("Test rejection."));
65 CHILD_TEST_PASSING
= """
66 function run_test () { run_next_test(); }
68 add_test(function test_child_simple () {
69 run_test_in_child("test_pass.js");
74 CHILD_TEST_FAILING
= """
75 function run_test () { run_next_test(); }
77 add_test(function test_child_simple () {
78 run_test_in_child("test_fail.js");
83 CHILD_HARNESS_SIMPLE
= """
84 function run_test () { run_next_test(); }
86 add_test(function test_child_assert () {
87 do_load_child_test_harness();
88 do_test_pending("test child assertion");
89 sendCommand("Assert.ok(true);", do_test_finished);
95 function run_test () { run_next_test(); }
97 add_test(function test_child_simple () {
98 do_test_pending("hang test");
99 do_load_child_test_harness();
100 sendCommand("_testLogger.info('CHILD-TEST-STARTED'); " +
101 + "const _TEST_FILE=['test_pass.js']; _execute_test(); ",
107 SIMPLE_LOOPING_TEST
= """
108 function run_test () { run_next_test(); }
110 add_test(function test_loop () {
115 PASSING_TEST_UNICODE
= b
"""
116 function run_test () { run_next_test(); }
118 add_test(function test_unicode_print () {
119 Assert.equal("\u201c\u201d", "\u201c\u201d");
124 ADD_TASK_SINGLE
= """
125 function run_test() { run_next_test(); }
127 add_task(async function test_task() {
128 await Promise.resolve(true);
129 await Promise.resolve(false);
133 ADD_TASK_MULTIPLE
= """
134 function run_test() { run_next_test(); }
136 add_task(async function test_task() {
137 await Promise.resolve(true);
140 add_task(async function test_2() {
141 await Promise.resolve(true);
145 ADD_TASK_REJECTED
= """
146 function run_test() { run_next_test(); }
148 add_task(async function test_failing() {
149 await Promise.reject(new Error("I fail."));
153 ADD_TASK_REJECTED_UNDEFINED
= """
154 function run_test() { run_next_test(); }
156 add_task(async function test_failing() {
157 await Promise.reject();
161 ADD_TASK_FAILURE_INSIDE
= """
162 function run_test() { run_next_test(); }
164 add_task(async function test() {
165 let result = await Promise.resolve(false);
171 ADD_TASK_RUN_NEXT_TEST
= """
172 function run_test() { run_next_test(); }
174 add_task(function () {
181 ADD_TASK_STACK_TRACE
= """
182 function run_test() { run_next_test(); }
184 add_task(async function this_test_will_fail() {
185 for (let i = 0; i < 10; ++i) {
186 await Promise.resolve();
193 add_task(async function skipMeNot1() {
194 Assert.ok(true, "Well well well.");
197 add_task(async function skipMe1() {
198 Assert.ok(false, "Not skipped after all.");
201 add_task(async function skipMeNot2() {
202 Assert.ok(true, "Well well well.");
205 add_task(async function skipMeNot3() {
206 Assert.ok(true, "Well well well.");
209 add_task(async function skipMe2() {
210 Assert.ok(false, "Not skipped after all.");
214 ADD_TASK_SKIPALL
= """
215 add_task(async function skipMe1() {
216 Assert.ok(false, "Not skipped after all.");
219 add_task(async function skipMe2() {
220 Assert.ok(false, "Not skipped after all.");
223 add_task(async function skipMe3() {
224 Assert.ok(false, "Not skipped after all.");
227 add_task(async function skipMeNot() {
228 Assert.ok(true, "Well well well.");
231 add_task(async function skipMe4() {
232 Assert.ok(false, "Not skipped after all.");
236 ADD_TEST_THROW_STRING
= """
237 function run_test() {do_throw("Passing a string to do_throw")};
240 ADD_TEST_THROW_OBJECT
= """
242 message: "Error object",
243 fileName: "failure.js",
244 stack: "ERROR STACK",
245 toString: function() {return this.message;}
247 function run_test() {do_throw(error)};
250 ADD_TEST_REPORT_OBJECT
= """
252 message: "Error object",
253 fileName: "failure.js",
254 stack: "ERROR STACK",
255 toString: function() {return this.message;}
257 function run_test() {do_report_unexpected_exception(error)};
260 ADD_TEST_VERBOSE
= """
261 function run_test() {info("a message from info")};
264 # A test for genuine JS-generated Error objects
265 ADD_TEST_REPORT_REF_ERROR
= """
266 function run_test() {
269 obj.noSuchFunction();
272 do_report_unexpected_exception(error);
277 # A test for failure to load a test due to a syntax error
278 LOAD_ERROR_SYNTAX_ERROR
= """
282 # A test for failure to load a test due to an error other than a syntax error
283 LOAD_ERROR_OTHER_ERROR
= """
285 no_such_var = "foo"; // assignment to undeclared variable
288 # A test that crashes outright.
290 function run_test () {
291 const { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
292 let zero = new ctypes.intptr_t(8);
293 let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
298 # A test for asynchronous cleanup functions
300 function run_test() {
301 let { PromiseUtils } = ChromeUtils.importESModule(
302 "resource://gre/modules/PromiseUtils.sys.mjs"
305 // The list of checkpoints in the order we encounter them.
306 let checkpoints = [];
308 // Cleanup tasks, in reverse order
309 registerCleanupFunction(function cleanup_checkout() {
310 Assert.equal(checkpoints.join(""), "123456");
311 info("At this stage, the test has succeeded");
312 do_throw("Throwing an error to force displaying the log");
315 registerCleanupFunction(function sync_cleanup_2() {
319 registerCleanupFunction(async function async_cleanup_4() {
324 registerCleanupFunction(async function async_cleanup_3() {
329 registerCleanupFunction(function async_cleanup_2() {
330 let deferred = PromiseUtils.defer();
331 executeSoon(deferred.resolve);
332 return deferred.promise.then(function() {
337 registerCleanupFunction(function sync_cleanup() {
341 registerCleanupFunction(function async_cleanup() {
342 let deferred = PromiseUtils.defer();
343 executeSoon(deferred.resolve);
344 return deferred.promise.then(function() {
352 # A test to check that add_test() tests run without run_test()
353 NO_RUN_TEST_ADD_TEST
= """
354 add_test(function no_run_test_add_test() {
360 # A test to check that add_task() tests run without run_test()
361 NO_RUN_TEST_ADD_TASK
= """
362 add_task(function no_run_test_add_task() {
367 # A test to check that both add_task() and add_test() work without run_test()
368 NO_RUN_TEST_ADD_TEST_ADD_TASK
= """
369 add_test(function no_run_test_add_test() {
374 add_task(function no_run_test_add_task() {
379 # A test to check that an empty test file without run_test(),
380 # add_test() or add_task() works.
381 NO_RUN_TEST_EMPTY_TEST
= """
382 // This is an empty test file.
385 NO_RUN_TEST_ADD_TEST_FAIL
= """
386 add_test(function no_run_test_add_test_fail() {
392 NO_RUN_TEST_ADD_TASK_FAIL
= """
393 add_task(function no_run_test_add_task_fail() {
398 NO_RUN_TEST_ADD_TASK_MULTIPLE
= """
399 add_task(async function test_task() {
400 await Promise.resolve(true);
403 add_task(async function test_2() {
404 await Promise.resolve(true);
409 function run_test() {
410 Assert.notEqual(typeof mozinfo, undefined);
411 Assert.notEqual(typeof mozinfo.os, undefined);
416 function run_test () { run_next_test(); }
418 add_test(function test_child_mozinfo () {
419 run_test_in_child("test_mozinfo.js");
425 add_task(function headless_true() {
426 Assert.equal(Services.env.get("MOZ_HEADLESS"), "1", "Check MOZ_HEADLESS");
427 Assert.equal(Services.env.get("DISPLAY"), "77", "Check DISPLAY");
432 add_task(function headless_false() {
433 Assert.notEqual(Services.env.get("MOZ_HEADLESS"), "1", "Check MOZ_HEADLESS");
434 Assert.notEqual(Services.env.get("DISPLAY"), "77", "Check DISPLAY");
439 class XPCShellTestsTests(unittest
.TestCase
):
441 Yes, these are unit tests for a unit test harness.
444 def __init__(self
, name
):
445 super(XPCShellTestsTests
, self
).__init
__(name
)
446 from buildconfig
import substs
447 from mozbuild
.base
import MozbuildObject
449 os
.environ
.pop("MOZ_OBJDIR", None)
450 self
.build_obj
= MozbuildObject
.from_environment()
452 objdir
= self
.build_obj
.topobjdir
453 self
.testing_modules
= os
.path
.join(objdir
, "_tests", "modules")
456 self
.xpcshellBin
= os
.path
.join(
459 substs
["MOZ_MACBUNDLE_NAME"],
465 self
.xpcshellBin
= os
.path
.join(objdir
, "dist", "bin", "xpcshell")
467 if sys
.platform
== "win32":
468 self
.xpcshellBin
+= ".exe"
469 self
.utility_path
= os
.path
.join(objdir
, "dist", "bin")
470 self
.symbols_path
= None
471 candidate_path
= os
.path
.join(self
.build_obj
.distdir
, "crashreporter-symbols")
472 if os
.path
.isdir(candidate_path
):
473 self
.symbols_path
= candidate_path
476 self
.log
= six
.StringIO()
477 self
.tempdir
= tempfile
.mkdtemp()
478 logger
= structured
.commandline
.setup_logging(
479 "selftest%s" % id(self
), {}, {"tbpl": self
.log
}
481 self
.x
= XPCShellTests(logger
)
482 self
.x
.harness_timeout
= 30 if not mozinfo
.info
["ccov"] else 60
485 shutil
.rmtree(self
.tempdir
)
486 self
.x
.shutdownNode()
488 def writeFile(self
, name
, contents
, mode
="w"):
490 Write |contents| to a file named |name| in the temp directory,
491 and return the full path to the file.
493 fullpath
= os
.path
.join(self
.tempdir
, name
)
494 with
open(fullpath
, mode
) as f
:
498 def writeManifest(self
, tests
, prefs
=[]):
500 Write an xpcshell.ini in the temp directory and set
501 self.manifest to its pathname. |tests| is a list containing
502 either strings (for test names), or tuples with a test name
503 as the first element and manifest conditions as the following
504 elements. |prefs| is an optional list of prefs in the form of
505 "prefname=prefvalue" strings.
509 testlines
.append("[%s]" % (t
if isinstance(t
, six
.string_types
) else t
[0]))
510 if isinstance(t
, tuple):
511 testlines
.extend(t
[1:])
514 # Append prefs lines as indented inside "prefs=" manifest option.
515 prefslines
.append(" %s" % p
)
517 self
.manifest
= self
.writeFile(
525 + "\n".join(prefslines
)
527 + "\n".join(testlines
),
530 def assertTestResult(self
, expected
, shuffle
=False, verbose
=False, headless
=False):
532 Assert that self.x.runTests with manifest=self.manifest
536 kwargs
["app_binary"] = self
.app_binary
537 kwargs
["xpcshell"] = self
.xpcshellBin
538 kwargs
["symbolsPath"] = self
.symbols_path
539 kwargs
["manifest"] = self
.manifest
540 kwargs
["mozInfo"] = mozinfo
.info
541 kwargs
["shuffle"] = shuffle
542 kwargs
["verbose"] = verbose
543 kwargs
["headless"] = headless
544 kwargs
["sequential"] = True
545 kwargs
["testingModulesDir"] = self
.testing_modules
546 kwargs
["utility_path"] = self
.utility_path
550 self
.x
.runTests(kwargs
),
551 msg
="""Tests should have %s, log:
556 % ("passed" if expected
else "failed", self
.log
.getvalue()),
559 def _assertLog(self
, s
, expected
):
560 l
= self
.log
.getvalue()
564 msg
="""Value %s %s in log:
568 % (s
, "expected" if expected
else "not expected", l
),
571 def assertInLog(self
, s
):
573 Assert that the string |s| is contained in self.log.
575 self
._assertLog
(s
, True)
577 def assertNotInLog(self
, s
):
579 Assert that the string |s| is not contained in self.log.
581 self
._assertLog
(s
, False)
585 Check that a simple test without any manifest conditions passes.
587 self
.writeFile("test_basic.js", SIMPLE_PASSING_TEST
)
588 self
.writeManifest(["test_basic.js"])
590 self
.assertTestResult(True)
591 self
.assertEqual(1, self
.x
.testCount
)
592 self
.assertEqual(1, self
.x
.passCount
)
593 self
.assertEqual(0, self
.x
.failCount
)
594 self
.assertEqual(0, self
.x
.todoCount
)
595 self
.assertInLog(TEST_PASS_STRING
)
596 self
.assertNotInLog(TEST_FAIL_STRING
)
600 Check that a simple failing test without any manifest conditions fails.
602 self
.writeFile("test_basic.js", SIMPLE_FAILING_TEST
)
603 self
.writeManifest(["test_basic.js"])
605 self
.assertTestResult(False)
606 self
.assertEqual(1, self
.x
.testCount
)
607 self
.assertEqual(0, self
.x
.passCount
)
608 self
.assertEqual(1, self
.x
.failCount
)
609 self
.assertEqual(0, self
.x
.todoCount
)
610 self
.assertInLog(TEST_FAIL_STRING
)
611 self
.assertNotInLog(TEST_PASS_STRING
)
613 def testPrefsInManifestVerbose(self
):
615 Check prefs configuration option is supported in xpcshell manifests.
617 self
.writeFile("test_prefs.js", SIMPLE_PREFCHECK_TEST
)
618 self
.writeManifest(tests
=["test_prefs.js"], prefs
=["fake.pref.to.test=true"])
620 self
.assertTestResult(True, verbose
=True)
621 self
.assertInLog(TEST_PASS_STRING
)
622 self
.assertNotInLog(TEST_FAIL_STRING
)
623 self
.assertEqual(1, self
.x
.testCount
)
624 self
.assertEqual(1, self
.x
.passCount
)
625 self
.assertInLog("Per-test extra prefs will be set:")
626 self
.assertInLog("fake.pref.to.test=true")
628 def testPrefsInManifestNonVerbose(self
):
630 Check prefs configuration are not logged in non verbose mode.
632 self
.writeFile("test_prefs.js", SIMPLE_PREFCHECK_TEST
)
633 self
.writeManifest(tests
=["test_prefs.js"], prefs
=["fake.pref.to.test=true"])
635 self
.assertTestResult(True, verbose
=False)
636 self
.assertNotInLog("Per-test extra prefs will be set:")
637 self
.assertNotInLog("fake.pref.to.test=true")
640 mozinfo
.isWin
or not mozinfo
.info
.get("debug"),
641 "We don't have a stack fixer on hand for windows.",
643 def testAssertStack(self
):
645 When an assertion is hit, we should produce a useful stack.
650 add_test(function test_asserts_immediately() {
651 Components.classes["@mozilla.org/xpcom/debug;1"]
652 .getService(Components.interfaces.nsIDebug2)
653 .assertion("foo", "assertion failed", "test.js", 1)
659 self
.writeManifest(["test_assert.js"])
660 self
.assertTestResult(False)
662 self
.assertInLog("###!!! ASSERTION")
663 log_lines
= self
.log
.getvalue().splitlines()
665 unknown_pat
= "#\d\d\: \?\?\?\[.* \+0x[a-f0-9]+\]"
667 any(re
.search(unknown_pat
, line
) for line
in log_lines
),
668 "An stack frame without symbols was found in\n%s"
669 % pprint
.pformat(log_lines
),
672 any(re
.search(line_pat
, line
) for line
in log_lines
),
673 "No line resembling a stack frame was found in\n%s"
674 % pprint
.pformat(log_lines
),
677 def testChildPass(self
):
679 Check that a simple test running in a child process passes.
681 self
.writeFile("test_pass.js", SIMPLE_PASSING_TEST
)
682 self
.writeFile("test_child_pass.js", CHILD_TEST_PASSING
)
683 self
.writeManifest(["test_child_pass.js"])
685 self
.assertTestResult(True, verbose
=True)
686 self
.assertEqual(1, self
.x
.testCount
)
687 self
.assertEqual(1, self
.x
.passCount
)
688 self
.assertEqual(0, self
.x
.failCount
)
689 self
.assertEqual(0, self
.x
.todoCount
)
690 self
.assertInLog(TEST_PASS_STRING
)
691 self
.assertInLog("CHILD-TEST-STARTED")
692 self
.assertInLog("CHILD-TEST-COMPLETED")
693 self
.assertNotInLog(TEST_FAIL_STRING
)
695 def testChildFail(self
):
697 Check that a simple failing test running in a child process fails.
699 self
.writeFile("test_fail.js", SIMPLE_FAILING_TEST
)
700 self
.writeFile("test_child_fail.js", CHILD_TEST_FAILING
)
701 self
.writeManifest(["test_child_fail.js"])
703 self
.assertTestResult(False)
704 self
.assertEqual(1, self
.x
.testCount
)
705 self
.assertEqual(0, self
.x
.passCount
)
706 self
.assertEqual(1, self
.x
.failCount
)
707 self
.assertEqual(0, self
.x
.todoCount
)
708 self
.assertInLog(TEST_FAIL_STRING
)
709 self
.assertInLog("CHILD-TEST-STARTED")
710 self
.assertInLog("CHILD-TEST-COMPLETED")
711 self
.assertNotInLog(TEST_PASS_STRING
)
713 def testChildHang(self
):
715 Check that incomplete output from a child process results in a
718 self
.writeFile("test_pass.js", SIMPLE_PASSING_TEST
)
719 self
.writeFile("test_child_hang.js", CHILD_TEST_HANG
)
720 self
.writeManifest(["test_child_hang.js"])
722 self
.assertTestResult(False)
723 self
.assertEqual(1, self
.x
.testCount
)
724 self
.assertEqual(0, self
.x
.passCount
)
725 self
.assertEqual(1, self
.x
.failCount
)
726 self
.assertEqual(0, self
.x
.todoCount
)
727 self
.assertInLog(TEST_FAIL_STRING
)
728 self
.assertInLog("CHILD-TEST-STARTED")
729 self
.assertNotInLog("CHILD-TEST-COMPLETED")
730 self
.assertNotInLog(TEST_PASS_STRING
)
734 Checks that calling do_load_child_test_harness without run_test_in_child
735 results in a usable test state. This test has a spurious failure when
736 run using |mach python-test|. See bug 1103226.
738 self
.writeFile("test_child_assertions.js", CHILD_HARNESS_SIMPLE
)
739 self
.writeManifest(["test_child_assertions.js"])
741 self
.assertTestResult(True)
742 self
.assertEqual(1, self
.x
.testCount
)
743 self
.assertEqual(1, self
.x
.passCount
)
744 self
.assertEqual(0, self
.x
.failCount
)
745 self
.assertEqual(0, self
.x
.todoCount
)
746 self
.assertInLog(TEST_PASS_STRING
)
747 self
.assertNotInLog(TEST_FAIL_STRING
)
749 def testSkipForAddTest(self
):
751 Check that add_test is skipped if |skip_if| condition is true
758 }, function test_should_be_skipped() {
764 self
.writeManifest(["test_skip.js"])
765 self
.assertTestResult(True, verbose
=True)
766 self
.assertEqual(1, self
.x
.testCount
)
767 self
.assertEqual(1, self
.x
.passCount
)
768 self
.assertEqual(0, self
.x
.failCount
)
769 self
.assertEqual(0, self
.x
.todoCount
)
770 self
.assertInLog(TEST_PASS_STRING
)
771 self
.assertInLog("TEST-SKIP")
772 self
.assertNotInLog(TEST_FAIL_STRING
)
774 def testNotSkipForAddTask(self
):
776 Check that add_task is not skipped if |skip_if| condition is false
782 skip_if: () => false,
783 }, function test_should_not_be_skipped() {
788 self
.writeManifest(["test_not_skip.js"])
789 self
.assertTestResult(True, verbose
=True)
790 self
.assertEqual(1, self
.x
.testCount
)
791 self
.assertEqual(1, self
.x
.passCount
)
792 self
.assertEqual(0, self
.x
.failCount
)
793 self
.assertEqual(0, self
.x
.todoCount
)
794 self
.assertInLog(TEST_PASS_STRING
)
795 self
.assertNotInLog("TEST-SKIP")
796 self
.assertNotInLog(TEST_FAIL_STRING
)
798 def testSkipForAddTask(self
):
800 Check that add_task is skipped if |skip_if| condition is true
807 }, function test_should_be_skipped() {
812 self
.writeManifest(["test_skip.js"])
813 self
.assertTestResult(True, verbose
=True)
814 self
.assertEqual(1, self
.x
.testCount
)
815 self
.assertEqual(1, self
.x
.passCount
)
816 self
.assertEqual(0, self
.x
.failCount
)
817 self
.assertEqual(0, self
.x
.todoCount
)
818 self
.assertInLog(TEST_PASS_STRING
)
819 self
.assertInLog("TEST-SKIP")
820 self
.assertNotInLog(TEST_FAIL_STRING
)
822 def testNotSkipForAddTest(self
):
824 Check that add_test is not skipped if |skip_if| condition is false
830 skip_if: () => false,
831 }, function test_should_not_be_skipped() {
837 self
.writeManifest(["test_not_skip.js"])
838 self
.assertTestResult(True, verbose
=True)
839 self
.assertEqual(1, self
.x
.testCount
)
840 self
.assertEqual(1, self
.x
.passCount
)
841 self
.assertEqual(0, self
.x
.failCount
)
842 self
.assertEqual(0, self
.x
.todoCount
)
843 self
.assertInLog(TEST_PASS_STRING
)
844 self
.assertNotInLog("TEST-SKIP")
845 self
.assertNotInLog(TEST_FAIL_STRING
)
847 def testSyntaxError(self
):
849 Check that running a test file containing a syntax error produces
850 a test failure and expected output.
852 self
.writeFile("test_syntax_error.js", '"')
853 self
.writeManifest(["test_syntax_error.js"])
855 self
.assertTestResult(False, verbose
=True)
856 self
.assertEqual(1, self
.x
.testCount
)
857 self
.assertEqual(0, self
.x
.passCount
)
858 self
.assertEqual(1, self
.x
.failCount
)
859 self
.assertEqual(0, self
.x
.todoCount
)
860 self
.assertInLog(TEST_FAIL_STRING
)
861 self
.assertNotInLog(TEST_PASS_STRING
)
863 def testUnicodeInAssertMethods(self
):
865 Check that passing unicode characters through an assertion method works.
867 self
.writeFile("test_unicode_assert.js", PASSING_TEST_UNICODE
, mode
="wb")
868 self
.writeManifest(["test_unicode_assert.js"])
870 self
.assertTestResult(True, verbose
=True)
873 "MOZ_AUTOMATION" in os
.environ
,
874 "Timeout code path occasionally times out (bug 1098121)",
876 def testHangingTimeout(self
):
878 Check that a test that never finishes results in the correct error log.
880 self
.writeFile("test_loop.js", SIMPLE_LOOPING_TEST
)
881 self
.writeManifest(["test_loop.js"])
883 old_timeout
= self
.x
.harness_timeout
884 self
.x
.harness_timeout
= 1
886 self
.assertTestResult(False)
887 self
.assertEqual(1, self
.x
.testCount
)
888 self
.assertEqual(1, self
.x
.failCount
)
889 self
.assertEqual(0, self
.x
.passCount
)
890 self
.assertEqual(0, self
.x
.todoCount
)
891 self
.assertInLog("TEST-UNEXPECTED-TIMEOUT")
893 self
.x
.harness_timeout
= old_timeout
895 def testPassFail(self
):
897 Check that running more than one test works.
899 self
.writeFile("test_pass.js", SIMPLE_PASSING_TEST
)
900 self
.writeFile("test_fail.js", SIMPLE_FAILING_TEST
)
901 self
.writeManifest(["test_pass.js", "test_fail.js"])
903 self
.assertTestResult(False)
904 self
.assertEqual(2, self
.x
.testCount
)
905 self
.assertEqual(1, self
.x
.passCount
)
906 self
.assertEqual(1, self
.x
.failCount
)
907 self
.assertEqual(0, self
.x
.todoCount
)
908 self
.assertInLog(TEST_PASS_STRING
)
909 self
.assertInLog(TEST_FAIL_STRING
)
913 Check that a simple failing test skipped in the manifest does
916 self
.writeFile("test_basic.js", SIMPLE_FAILING_TEST
)
917 self
.writeManifest([("test_basic.js", "skip-if = true")])
918 self
.assertTestResult(True)
919 self
.assertEqual(1, self
.x
.testCount
)
920 self
.assertEqual(0, self
.x
.passCount
)
921 self
.assertEqual(0, self
.x
.failCount
)
922 self
.assertEqual(0, self
.x
.todoCount
)
923 self
.assertNotInLog(TEST_FAIL_STRING
)
924 self
.assertNotInLog(TEST_PASS_STRING
)
926 def testKnownFail(self
):
928 Check that a simple failing test marked as known-fail in the manifest
929 does not cause failure.
931 self
.writeFile("test_basic.js", SIMPLE_FAILING_TEST
)
932 self
.writeManifest([("test_basic.js", "fail-if = true")])
933 self
.assertTestResult(True)
934 self
.assertEqual(1, self
.x
.testCount
)
935 self
.assertEqual(0, self
.x
.passCount
)
936 self
.assertEqual(0, self
.x
.failCount
)
937 self
.assertEqual(1, self
.x
.todoCount
)
938 self
.assertInLog("TEST-FAIL")
939 # This should be suppressed because the harness doesn't include
940 # the full log from the xpcshell run when things pass.
941 self
.assertNotInLog(TEST_FAIL_STRING
)
942 self
.assertNotInLog(TEST_PASS_STRING
)
944 def testUnexpectedPass(self
):
946 Check that a simple failing test marked as known-fail in the manifest
947 that passes causes an unexpected pass.
949 self
.writeFile("test_basic.js", SIMPLE_PASSING_TEST
)
950 self
.writeManifest([("test_basic.js", "fail-if = true")])
951 self
.assertTestResult(False)
952 self
.assertEqual(1, self
.x
.testCount
)
953 self
.assertEqual(0, self
.x
.passCount
)
954 self
.assertEqual(1, self
.x
.failCount
)
955 self
.assertEqual(0, self
.x
.todoCount
)
956 # From the outer (Python) harness
957 self
.assertInLog("TEST-UNEXPECTED-PASS")
958 self
.assertNotInLog("TEST-KNOWN-FAIL")
960 def testReturnNonzero(self
):
962 Check that a test where xpcshell returns nonzero fails.
964 self
.writeFile("test_error.js", "throw 'foo'")
965 self
.writeManifest(["test_error.js"])
967 self
.assertTestResult(False)
968 self
.assertEqual(1, self
.x
.testCount
)
969 self
.assertEqual(0, self
.x
.passCount
)
970 self
.assertEqual(1, self
.x
.failCount
)
971 self
.assertEqual(0, self
.x
.todoCount
)
972 self
.assertInLog(TEST_FAIL_STRING
)
973 self
.assertNotInLog(TEST_PASS_STRING
)
975 def testUncaughtRejection(self
):
977 Ensure a simple test with an uncaught rejection is reported.
980 "test_simple_uncaught_rejection.js", SIMPLE_UNCAUGHT_REJECTION_TEST
982 self
.writeManifest(["test_simple_uncaught_rejection.js"])
984 self
.assertTestResult(False)
985 self
.assertInLog(TEST_FAIL_STRING
)
986 self
.assertInLog("test_simple_uncaught_rejection.js:3:18")
987 self
.assertInLog("Test rejection.")
988 self
.assertEqual(1, self
.x
.testCount
)
989 self
.assertEqual(0, self
.x
.passCount
)
990 self
.assertEqual(1, self
.x
.failCount
)
992 def testAddTestSimple(self
):
994 Ensure simple add_test() works.
996 self
.writeFile("test_add_test_simple.js", ADD_TEST_SIMPLE
)
997 self
.writeManifest(["test_add_test_simple.js"])
999 self
.assertTestResult(True)
1000 self
.assertEqual(1, self
.x
.testCount
)
1001 self
.assertEqual(1, self
.x
.passCount
)
1002 self
.assertEqual(0, self
.x
.failCount
)
1004 def testCrashLogging(self
):
1006 Test that a crashing test process logs a failure.
1008 self
.writeFile("test_crashes.js", TEST_CRASHING
)
1009 self
.writeManifest(["test_crashes.js"])
1011 self
.assertTestResult(False)
1012 self
.assertEqual(1, self
.x
.testCount
)
1013 self
.assertEqual(0, self
.x
.passCount
)
1014 self
.assertEqual(1, self
.x
.failCount
)
1015 if mozinfo
.info
.get("crashreporter"):
1016 self
.assertInLog("\nPROCESS-CRASH")
1018 def testLogCorrectFileName(self
):
1020 Make sure a meaningful filename and line number is logged
1023 self
.writeFile("test_add_test_simple.js", ADD_TEST_SIMPLE
)
1024 self
.writeManifest(["test_add_test_simple.js"])
1026 self
.assertTestResult(True, verbose
=True)
1027 self
.assertInLog("true == true")
1028 self
.assertNotInLog("[Assert.ok :")
1029 self
.assertInLog("[test_simple : 5]")
1031 def testAddTestFailing(self
):
1033 Ensure add_test() with a failing test is reported.
1035 self
.writeFile("test_add_test_failing.js", ADD_TEST_FAILING
)
1036 self
.writeManifest(["test_add_test_failing.js"])
1038 self
.assertTestResult(False)
1039 self
.assertEqual(1, self
.x
.testCount
)
1040 self
.assertEqual(0, self
.x
.passCount
)
1041 self
.assertEqual(1, self
.x
.failCount
)
1043 def testAddTestUncaughtRejection(self
):
1045 Ensure add_test() with an uncaught rejection is reported.
1048 "test_add_test_uncaught_rejection.js", ADD_TEST_UNCAUGHT_REJECTION
1050 self
.writeManifest(["test_add_test_uncaught_rejection.js"])
1052 self
.assertTestResult(False)
1053 self
.assertEqual(1, self
.x
.testCount
)
1054 self
.assertEqual(0, self
.x
.passCount
)
1055 self
.assertEqual(1, self
.x
.failCount
)
1057 def testAddTaskTestSingle(self
):
1059 Ensure add_test_task() with a single passing test works.
1061 self
.writeFile("test_add_task_simple.js", ADD_TASK_SINGLE
)
1062 self
.writeManifest(["test_add_task_simple.js"])
1064 self
.assertTestResult(True)
1065 self
.assertEqual(1, self
.x
.testCount
)
1066 self
.assertEqual(1, self
.x
.passCount
)
1067 self
.assertEqual(0, self
.x
.failCount
)
1069 def testAddTaskTestMultiple(self
):
1071 Ensure multiple calls to add_test_task() work as expected.
1073 self
.writeFile("test_add_task_multiple.js", ADD_TASK_MULTIPLE
)
1074 self
.writeManifest(["test_add_task_multiple.js"])
1076 self
.assertTestResult(True)
1077 self
.assertEqual(1, self
.x
.testCount
)
1078 self
.assertEqual(1, self
.x
.passCount
)
1079 self
.assertEqual(0, self
.x
.failCount
)
1081 def testAddTaskTestRejected(self
):
1083 Ensure rejected task reports as failure.
1085 self
.writeFile("test_add_task_rejected.js", ADD_TASK_REJECTED
)
1086 self
.writeManifest(["test_add_task_rejected.js"])
1088 self
.assertTestResult(False)
1089 self
.assertEqual(1, self
.x
.testCount
)
1090 self
.assertEqual(0, self
.x
.passCount
)
1091 self
.assertEqual(1, self
.x
.failCount
)
1093 def testAddTaskTestRejectedUndefined(self
):
1095 Ensure rejected task with undefined reason reports as failure and does not hang.
1098 "test_add_task_rejected_undefined.js", ADD_TASK_REJECTED_UNDEFINED
1100 self
.writeManifest(["test_add_task_rejected_undefined.js"])
1102 self
.assertTestResult(False)
1103 self
.assertEqual(1, self
.x
.testCount
)
1104 self
.assertEqual(0, self
.x
.passCount
)
1105 self
.assertEqual(1, self
.x
.failCount
)
1106 self
.assertNotInLog("TEST-UNEXPECTED-TIMEOUT")
1108 def testAddTaskTestFailureInside(self
):
1110 Ensure tests inside task are reported as failures.
1112 self
.writeFile("test_add_task_failure_inside.js", ADD_TASK_FAILURE_INSIDE
)
1113 self
.writeManifest(["test_add_task_failure_inside.js"])
1115 self
.assertTestResult(False)
1116 self
.assertEqual(1, self
.x
.testCount
)
1117 self
.assertEqual(0, self
.x
.passCount
)
1118 self
.assertEqual(1, self
.x
.failCount
)
1120 def testAddTaskRunNextTest(self
):
1122 Calling run_next_test() from inside add_task() results in failure.
1124 self
.writeFile("test_add_task_run_next_test.js", ADD_TASK_RUN_NEXT_TEST
)
1125 self
.writeManifest(["test_add_task_run_next_test.js"])
1127 self
.assertTestResult(False)
1128 self
.assertEqual(1, self
.x
.testCount
)
1129 self
.assertEqual(0, self
.x
.passCount
)
1130 self
.assertEqual(1, self
.x
.failCount
)
1132 def testAddTaskStackTrace(self
):
1134 Ensuring that calling Assert.ok(false) from inside add_task()
1135 results in a human-readable stack trace.
1137 self
.writeFile("test_add_task_stack_trace.js", ADD_TASK_STACK_TRACE
)
1138 self
.writeManifest(["test_add_task_stack_trace.js"])
1140 self
.assertTestResult(False)
1141 self
.assertInLog("this_test_will_fail")
1142 self
.assertInLog("run_next_test")
1143 self
.assertInLog("run_test")
1144 self
.assertNotInLog("Task.jsm")
1146 def testAddTaskSkip(self
):
1147 self
.writeFile("test_tasks_skip.js", ADD_TASK_SKIP
)
1148 self
.writeManifest(["test_tasks_skip.js"])
1150 self
.assertTestResult(True)
1151 self
.assertEqual(1, self
.x
.testCount
)
1152 self
.assertEqual(1, self
.x
.passCount
)
1153 self
.assertEqual(0, self
.x
.failCount
)
1155 def testAddTaskSkipAll(self
):
1156 self
.writeFile("test_tasks_skipall.js", ADD_TASK_SKIPALL
)
1157 self
.writeManifest(["test_tasks_skipall.js"])
1159 self
.assertTestResult(True)
1160 self
.assertEqual(1, self
.x
.testCount
)
1161 self
.assertEqual(1, self
.x
.passCount
)
1162 self
.assertEqual(0, self
.x
.failCount
)
1164 def testMissingHeadFile(self
):
1166 Ensure that missing head file results in fatal failure.
1168 self
.writeFile("test_basic.js", SIMPLE_PASSING_TEST
)
1169 self
.writeManifest([("test_basic.js", "head = missing.js")])
1174 # The actual return value is never checked because we raise.
1175 self
.assertTestResult(True)
1176 except Exception as ex
:
1178 self
.assertEqual(str(ex
)[0:9], "head file")
1180 self
.assertTrue(raised
)
1182 def testRandomExecution(self
):
1184 Check that random execution doesn't break.
1187 for i
in range(0, 10):
1188 filename
= "test_pass_%d.js" % i
1189 self
.writeFile(filename
, SIMPLE_PASSING_TEST
)
1190 manifest
.append(filename
)
1192 self
.writeManifest(manifest
)
1193 self
.assertTestResult(True, shuffle
=True)
1194 self
.assertEqual(10, self
.x
.testCount
)
1195 self
.assertEqual(10, self
.x
.passCount
)
1197 def testDoThrowString(self
):
1199 Check that do_throw produces reasonable messages when the
1200 input is a string instead of an object
1202 self
.writeFile("test_error.js", ADD_TEST_THROW_STRING
)
1203 self
.writeManifest(["test_error.js"])
1205 self
.assertTestResult(False)
1206 self
.assertInLog(TEST_FAIL_STRING
)
1207 self
.assertInLog("Passing a string to do_throw")
1208 self
.assertNotInLog(TEST_PASS_STRING
)
1210 def testDoThrowForeignObject(self
):
1212 Check that do_throw produces reasonable messages when the
1213 input is a generic object with 'filename', 'message' and 'stack' attributes
1214 but 'object instanceof Error' returns false
1216 self
.writeFile("test_error.js", ADD_TEST_THROW_OBJECT
)
1217 self
.writeManifest(["test_error.js"])
1219 self
.assertTestResult(False)
1220 self
.assertInLog(TEST_FAIL_STRING
)
1221 self
.assertInLog("failure.js")
1222 self
.assertInLog("Error object")
1223 self
.assertInLog("ERROR STACK")
1224 self
.assertNotInLog(TEST_PASS_STRING
)
1226 def testDoReportForeignObject(self
):
1228 Check that do_report_unexpected_exception produces reasonable messages when the
1229 input is a generic object with 'filename', 'message' and 'stack' attributes
1230 but 'object instanceof Error' returns false
1232 self
.writeFile("test_error.js", ADD_TEST_REPORT_OBJECT
)
1233 self
.writeManifest(["test_error.js"])
1235 self
.assertTestResult(False)
1236 self
.assertInLog(TEST_FAIL_STRING
)
1237 self
.assertInLog("failure.js")
1238 self
.assertInLog("Error object")
1239 self
.assertInLog("ERROR STACK")
1240 self
.assertNotInLog(TEST_PASS_STRING
)
1242 def testDoReportRefError(self
):
1244 Check that do_report_unexpected_exception produces reasonable messages when the
1245 input is a JS-generated Error
1247 self
.writeFile("test_error.js", ADD_TEST_REPORT_REF_ERROR
)
1248 self
.writeManifest(["test_error.js"])
1250 self
.assertTestResult(False)
1251 self
.assertInLog(TEST_FAIL_STRING
)
1252 self
.assertInLog("test_error.js")
1253 self
.assertInLog("obj.noSuchFunction is not a function")
1254 self
.assertInLog("run_test@")
1255 self
.assertNotInLog(TEST_PASS_STRING
)
1257 def testDoReportSyntaxError(self
):
1259 Check that attempting to load a test file containing a syntax error
1260 generates details of the error in the log
1262 self
.writeFile("test_error.js", LOAD_ERROR_SYNTAX_ERROR
)
1263 self
.writeManifest(["test_error.js"])
1265 self
.assertTestResult(False)
1266 self
.assertInLog(TEST_FAIL_STRING
)
1267 self
.assertInLog("test_error.js:3")
1268 self
.assertNotInLog(TEST_PASS_STRING
)
1270 def testDoReportNonSyntaxError(self
):
1272 Check that attempting to load a test file containing an error other
1273 than a syntax error generates details of the error in the log
1275 self
.writeFile("test_error.js", LOAD_ERROR_OTHER_ERROR
)
1276 self
.writeManifest(["test_error.js"])
1278 self
.assertTestResult(False)
1279 self
.assertInLog(TEST_FAIL_STRING
)
1280 self
.assertInLog("ReferenceError: assignment to undeclared variable")
1281 self
.assertInLog("test_error.js:3")
1282 self
.assertNotInLog(TEST_PASS_STRING
)
1284 def testDoPrintWhenVerboseNotExplicit(self
):
1286 Check that info() and similar calls that generate output do
1287 not have the output when not run verbosely.
1289 self
.writeFile("test_verbose.js", ADD_TEST_VERBOSE
)
1290 self
.writeManifest(["test_verbose.js"])
1292 self
.assertTestResult(True)
1293 self
.assertNotInLog("a message from info")
1295 def testDoPrintWhenVerboseExplicit(self
):
1297 Check that info() and similar calls that generate output have the
1298 output shown when run verbosely.
1300 self
.writeFile("test_verbose.js", ADD_TEST_VERBOSE
)
1301 self
.writeManifest(["test_verbose.js"])
1302 self
.assertTestResult(True, verbose
=True)
1303 self
.assertInLog("a message from info")
1305 def testDoPrintWhenVerboseInManifest(self
):
1307 Check that info() and similar calls that generate output have the
1308 output shown when 'verbose = true' is in the manifest, even when
1311 self
.writeFile("test_verbose.js", ADD_TEST_VERBOSE
)
1312 self
.writeManifest([("test_verbose.js", "verbose = true")])
1314 self
.assertTestResult(True)
1315 self
.assertInLog("a message from info")
1317 def testAsyncCleanup(self
):
1319 Check that registerCleanupFunction handles nicely async cleanup tasks
1321 self
.writeFile("test_asyncCleanup.js", ASYNC_CLEANUP
)
1322 self
.writeManifest(["test_asyncCleanup.js"])
1323 self
.assertTestResult(False)
1324 self
.assertInLog('"123456" == "123456"')
1325 self
.assertInLog("At this stage, the test has succeeded")
1326 self
.assertInLog("Throwing an error to force displaying the log")
1328 def testNoRunTestAddTest(self
):
1330 Check that add_test() works fine without run_test() in the test file.
1332 self
.writeFile("test_noRunTestAddTest.js", NO_RUN_TEST_ADD_TEST
)
1333 self
.writeManifest(["test_noRunTestAddTest.js"])
1335 self
.assertTestResult(True)
1336 self
.assertEqual(1, self
.x
.testCount
)
1337 self
.assertEqual(1, self
.x
.passCount
)
1338 self
.assertEqual(0, self
.x
.failCount
)
1339 self
.assertInLog(TEST_PASS_STRING
)
1340 self
.assertNotInLog(TEST_FAIL_STRING
)
1342 def testNoRunTestAddTask(self
):
1344 Check that add_task() works fine without run_test() in the test file.
1346 self
.writeFile("test_noRunTestAddTask.js", NO_RUN_TEST_ADD_TASK
)
1347 self
.writeManifest(["test_noRunTestAddTask.js"])
1349 self
.assertTestResult(True)
1350 self
.assertEqual(1, self
.x
.testCount
)
1351 self
.assertEqual(1, self
.x
.passCount
)
1352 self
.assertEqual(0, self
.x
.failCount
)
1353 self
.assertInLog(TEST_PASS_STRING
)
1354 self
.assertNotInLog(TEST_FAIL_STRING
)
1356 def testNoRunTestAddTestAddTask(self
):
1358 Check that both add_test() and add_task() work without run_test()
1361 self
.writeFile("test_noRunTestAddTestAddTask.js", NO_RUN_TEST_ADD_TEST_ADD_TASK
)
1362 self
.writeManifest(["test_noRunTestAddTestAddTask.js"])
1364 self
.assertTestResult(True)
1365 self
.assertEqual(1, self
.x
.testCount
)
1366 self
.assertEqual(1, self
.x
.passCount
)
1367 self
.assertEqual(0, self
.x
.failCount
)
1368 self
.assertInLog(TEST_PASS_STRING
)
1369 self
.assertNotInLog(TEST_FAIL_STRING
)
1371 def testNoRunTestEmptyTest(self
):
1373 Check that the test passes on an empty file that contains neither
1374 run_test() nor add_test(), add_task().
1376 self
.writeFile("test_noRunTestEmptyTest.js", NO_RUN_TEST_EMPTY_TEST
)
1377 self
.writeManifest(["test_noRunTestEmptyTest.js"])
1379 self
.assertTestResult(True)
1380 self
.assertEqual(1, self
.x
.testCount
)
1381 self
.assertEqual(1, self
.x
.passCount
)
1382 self
.assertEqual(0, self
.x
.failCount
)
1383 self
.assertInLog(TEST_PASS_STRING
)
1384 self
.assertNotInLog(TEST_FAIL_STRING
)
1386 def testNoRunTestAddTestFail(self
):
1388 Check that test fails on using add_test() without run_test().
1390 self
.writeFile("test_noRunTestAddTestFail.js", NO_RUN_TEST_ADD_TEST_FAIL
)
1391 self
.writeManifest(["test_noRunTestAddTestFail.js"])
1393 self
.assertTestResult(False)
1394 self
.assertEqual(1, self
.x
.testCount
)
1395 self
.assertEqual(0, self
.x
.passCount
)
1396 self
.assertEqual(1, self
.x
.failCount
)
1397 self
.assertInLog(TEST_FAIL_STRING
)
1398 self
.assertNotInLog(TEST_PASS_STRING
)
1400 def testNoRunTestAddTaskFail(self
):
1402 Check that test fails on using add_task() without run_test().
1404 self
.writeFile("test_noRunTestAddTaskFail.js", NO_RUN_TEST_ADD_TASK_FAIL
)
1405 self
.writeManifest(["test_noRunTestAddTaskFail.js"])
1407 self
.assertTestResult(False)
1408 self
.assertEqual(1, self
.x
.testCount
)
1409 self
.assertEqual(0, self
.x
.passCount
)
1410 self
.assertEqual(1, self
.x
.failCount
)
1411 self
.assertInLog(TEST_FAIL_STRING
)
1412 self
.assertNotInLog(TEST_PASS_STRING
)
1414 def testNoRunTestAddTaskMultiple(self
):
1416 Check that multple add_task() tests work without run_test().
1419 "test_noRunTestAddTaskMultiple.js", NO_RUN_TEST_ADD_TASK_MULTIPLE
1421 self
.writeManifest(["test_noRunTestAddTaskMultiple.js"])
1423 self
.assertTestResult(True)
1424 self
.assertEqual(1, self
.x
.testCount
)
1425 self
.assertEqual(1, self
.x
.passCount
)
1426 self
.assertEqual(0, self
.x
.failCount
)
1427 self
.assertInLog(TEST_PASS_STRING
)
1428 self
.assertNotInLog(TEST_FAIL_STRING
)
1430 def testMozinfo(self
):
1432 Check that mozinfo.json is loaded
1434 self
.writeFile("test_mozinfo.js", LOAD_MOZINFO
)
1435 self
.writeManifest(["test_mozinfo.js"])
1436 self
.assertTestResult(True)
1437 self
.assertEqual(1, self
.x
.testCount
)
1438 self
.assertEqual(1, self
.x
.passCount
)
1439 self
.assertEqual(0, self
.x
.failCount
)
1440 self
.assertEqual(0, self
.x
.todoCount
)
1441 self
.assertInLog(TEST_PASS_STRING
)
1442 self
.assertNotInLog(TEST_FAIL_STRING
)
1444 def testChildMozinfo(self
):
1446 Check that mozinfo.json is loaded in child process
1448 self
.writeFile("test_mozinfo.js", LOAD_MOZINFO
)
1449 self
.writeFile("test_child_mozinfo.js", CHILD_MOZINFO
)
1450 self
.writeManifest(["test_child_mozinfo.js"])
1451 self
.assertTestResult(True)
1452 self
.assertEqual(1, self
.x
.testCount
)
1453 self
.assertEqual(1, self
.x
.passCount
)
1454 self
.assertEqual(0, self
.x
.failCount
)
1455 self
.assertEqual(0, self
.x
.todoCount
)
1456 self
.assertInLog(TEST_PASS_STRING
)
1457 self
.assertNotInLog(TEST_FAIL_STRING
)
1459 def testNotHeadlessByDefault(self
):
1461 Check that the default is not headless.
1463 self
.writeFile("test_notHeadlessByDefault.js", HEADLESS_FALSE
)
1464 self
.writeManifest(["test_notHeadlessByDefault.js"])
1465 self
.assertTestResult(True)
1467 def testHeadlessWhenHeadlessExplicit(self
):
1469 Check that explicitly requesting headless works when the manifest doesn't override.
1471 self
.writeFile("test_headlessWhenExplicit.js", HEADLESS_TRUE
)
1472 self
.writeManifest(["test_headlessWhenExplicit.js"])
1473 self
.assertTestResult(True, headless
=True)
1475 def testHeadlessWhenHeadlessTrueInManifest(self
):
1477 Check that enabling headless in the manifest alone works.
1479 self
.writeFile("test_headlessWhenTrueInManifest.js", HEADLESS_TRUE
)
1480 self
.writeManifest([("test_headlessWhenTrueInManifest.js", "headless = true")])
1481 self
.assertTestResult(True)
1483 def testNotHeadlessWhenHeadlessFalseInManifest(self
):
1485 Check that the manifest entry overrides the explicit default.
1487 self
.writeFile("test_notHeadlessWhenFalseInManifest.js", HEADLESS_FALSE
)
1489 [("test_notHeadlessWhenFalseInManifest.js", "headless = false")]
1491 self
.assertTestResult(True, headless
=True)
1494 if __name__
== "__main__":
1497 mozinfo
.find_and_update_from_json()