test_SpecialPowersSandbox.html (5542B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test for SpecialPowers sandboxes</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 7 </head> 8 <body> 9 10 <iframe id="iframe"></iframe> 11 12 <script> 13 /** 14 * Tests that the shared sandbox functionality for cross-process script 15 * execution works as expected. In particular, ensures that Assert methods 16 * report the correct diagnostics in the caller scope. 17 */ 18 19 /* globals SpecialPowers, Assert */ 20 21 async function interceptDiagnostics(func) { 22 let originalRecord = SimpleTest.record; 23 try { 24 let diags = []; 25 26 SimpleTest.record = (condition, name, diag, stack) => { 27 diags.push({condition, name, diag, stack}); 28 }; 29 30 await func(); 31 32 return diags; 33 } finally { 34 SimpleTest.record = originalRecord; 35 } 36 } 37 38 add_task(async function() { 39 const frameSrc = "https://example.com/tests/testing/mochitest/tests/Harness_sanity/file_spawn.html"; 40 const subframeSrc = "https://example.org/tests/testing/mochitest/tests/Harness_sanity/file_spawn.html"; 41 42 let frame = document.getElementById("iframe"); 43 frame.src = frameSrc; 44 45 await new Promise(resolve => { 46 frame.addEventListener("load", resolve, {once: true}); 47 }); 48 49 let expected = [ 50 [false, "Thing - 1 == 2", "got 1, expected 2 (operator ==)"], 51 [true, "Hmm - 1 == 1", undefined], 52 [true, "Yay. - true == true", undefined], 53 [false, "Boo!. - false == true", "got false, expected true (operator ==)"], 54 [false, "Missing expected exception Rej_bad", "got null, expected /./ (operator undefined)"], 55 [true, "Rej_ok", undefined], 56 ]; 57 58 // Test that a representative variety of assertions work as expected, and 59 // trigger the expected calls to the harness's reporting function. 60 // 61 // Note: Assert.sys.mjs has its own tests, and defers all of its reporting to a 62 // single reporting function, so we don't need to test it comprehensively. We 63 // just need to make sure that the general functionality works as expected. 64 let tests = { 65 "SpecialPowers.spawn": () => { 66 return SpecialPowers.spawn(frame, [], async () => { 67 Assert.equal(1, 2, "Thing"); 68 Assert.equal(1, 1, "Hmm"); 69 Assert.ok(true, "Yay."); 70 Assert.ok(false, "Boo!."); 71 await Assert.rejects(Promise.resolve(), /./, "Rej_bad"); 72 await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok"); 73 }); 74 }, 75 "SpecialPowers.spawn-subframe": () => { 76 return SpecialPowers.spawn(frame, [subframeSrc], async src => { 77 let subFrame = this.content.document.createElement("iframe"); 78 subFrame.src = src; 79 this.content.document.body.appendChild(subFrame); 80 81 await new Promise(resolve => { 82 subFrame.addEventListener("load", resolve, { once: true }); 83 }); 84 85 await SpecialPowers.spawn(subFrame, [], async () => { 86 Assert.equal(1, 2, "Thing"); 87 Assert.equal(1, 1, "Hmm"); 88 Assert.ok(true, "Yay."); 89 Assert.ok(false, "Boo!."); 90 await Assert.rejects(Promise.resolve(), /./, "Rej_bad"); 91 await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok"); 92 }); 93 }); 94 }, 95 "SpecialPowers.spawnChrome": () => { 96 return SpecialPowers.spawnChrome([], async () => { 97 Assert.equal(1, 2, "Thing"); 98 Assert.equal(1, 1, "Hmm"); 99 Assert.ok(true, "Yay."); 100 Assert.ok(false, "Boo!."); 101 await Assert.rejects(Promise.resolve(), /./, "Rej_bad"); 102 await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok"); 103 }); 104 }, 105 "SpecialPowers.loadChromeScript": async () => { 106 let script = SpecialPowers.loadChromeScript(() => { 107 /* eslint-env mozilla/chrome-script */ 108 const resultPromise = (async () => { 109 Assert.equal(1, 2, "Thing"); 110 Assert.equal(1, 1, "Hmm"); 111 Assert.ok(true, "Yay."); 112 Assert.ok(false, "Boo!."); 113 await Assert.rejects(Promise.resolve(), /./, "Rej_bad"); 114 await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok"); 115 })(); 116 this.addMessageListener("ping", () => resultPromise); 117 }); 118 119 await script.sendQuery("ping"); 120 script.destroy(); 121 }, 122 }; 123 124 for (let [name, func] of Object.entries(tests)) { 125 info(`Starting task: ${name}`); 126 127 let diags = await interceptDiagnostics(func); 128 129 let results = diags.map(diag => [diag.condition, diag.name, diag.diag]); 130 131 isDeeply(results, expected, "Got expected assertions"); 132 for (let { name: diagName, stack } of diags) { 133 ok(stack, `Got stack for: ${diagName}`); 134 // Unlike test_SpecialPowersSandbox.js, expectedFilenamePart does not end 135 // with ":" (separator between file name and line number). This is because 136 // xorigin tests run this test file with a query param ("currentTestURL"), 137 // and the name therefore looks like "test_SpecialPowersSandbox.html?...:" 138 // instead of "test_SpecialPowersSandbox.html:" 139 let expectedFilenamePart = "/test_SpecialPowersSandbox.html"; 140 if (name === "SpecialPowers.loadChromeScript") { 141 // Unfortunately, the original file name is not included; 142 // the function name or a dummy value is used instead. 143 expectedFilenamePart = "loadChromeScript anonymous function>"; 144 } 145 if (!stack.includes(expectedFilenamePart)) { 146 ok(false, `Stack does not contain ${expectedFilenamePart}: ${stack}`); 147 } 148 } 149 } 150 }); 151 </script> 152 </body> 153 </html>