/* * Copyright (C) 2013-2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This namespace is injected into every test page. Its functions are invoked by // InspectorTest methods on the inspector page via a TestHarness subclass. TestPage = {}; TestPage._initializers = []; // Helper scripts like `debugger-test.js` must register their initialization // function with this method so it will be marshalled to the inspector page. TestPage.registerInitializer = function(initializer) { if (typeof initializer === "function") this._initializers.push(initializer.toString()); } // This function is called by the test document's body onload handler. // It initializes the inspector and loads any `*-test.js` helper scripts // into the inspector page context. function runTest() { // Don't try to use testRunner if running through the browser. if (!window.testRunner) return; // Set up the test page before the load event fires. testRunner.dumpAsText(); testRunner.waitUntilDone(); window.internals.setInspectorIsUnderTest(true); testRunner.showWebInspector(); let testFunction = window.test; if (typeof testFunction !== "function") { alert("Failed to send test() because it is not a function."); testRunner.notifyDone(); } function runInitializationMethodsInFrontend(initializersArray) { InspectorTest.testPageDidLoad(); // If the test page reloaded but we started running the test in a previous // navigation, then don't initialize the inspector frontend again. if (InspectorTest.didInjectTestCode) return; for (let initializer of initializersArray) { try { initializer(); } catch (e) { console.error("Exception in test initialization: " + e, e.stack || "(no stack trace)"); InspectorTest.completeTest(); } } } function runTestMethodInFrontend(testFunction) { if (InspectorTest.didInjectTestCode) return; InspectorTest.didInjectTestCode = true; try { testFunction(); } catch (e) { // Using this instead of window.onerror will preserve the stack trace. e.code = testFunction.toString(); InspectorTest.reportUncaughtException(e); } } let initializationCodeString = `(${runInitializationMethodsInFrontend.toString()})([${TestPage._initializers}]);`; let testFunctionCodeString = `(${runTestMethodInFrontend.toString()})(${testFunction.toString()});`; TestPage.evaluateInWebInspector(initializationCodeString); TestPage.evaluateInWebInspector(testFunctionCodeString); } function runTestHTTPS() { if (window.testRunner) { testRunner.dumpAsText(); testRunner.waitUntilDone(); } let url = new URL(document.URL); if (url.protocol !== "https:") { url.protocol = "https:"; url.port = "8443"; window.location.href = url.toString(); return; } runTest(); } TestPage.completeTest = function() { // Don't try to use testRunner if running through the browser. if (!window.testRunner) return; // Close inspector asynchrously in case we want to test tear-down behavior. setTimeout(() => { testRunner.closeWebInspector(); setTimeout(() => { testRunner.notifyDone(); }, 0); }, 0); } // Logs message to unbuffered process stdout, avoiding timeouts. // only be used to debug tests and not to produce normal test output. TestPage.debugLog = function(message) { window.alert(message); } // Use this to dump evaluations that are sent from the TestPage to the InspectorTest page. TestPage.debug = function() { this.dumpInspectorPageEvaluations = true; } TestPage.evaluateInWebInspector = function(code) { if (this.dumpInspectorPageEvaluations) this.debugLog(code); testRunner.evaluateInWebInspector(code); } // Add and clear test output from the results window. TestPage.addResult = function(text) { // For early errors triggered when loading the test page, write to stderr. if (!document.body) { this.debugLog(text); this.completeTest(); } if (!this._resultElement) { this._resultElement = document.createElement("pre"); this._resultElement.id = "output"; document.body.appendChild(this._resultElement); } this._resultElement.append(text, document.createElement("br")); } TestPage.log = TestPage.addResult; TestPage.clearOutput = function() { if (!this._resultElement) return; let output = this._resultElement; while (output.firstChild) output.removeChild(output.firstChild); } TestPage.dispatchEventToFrontend = function(eventName, data) { let dispatchEventCodeString = `InspectorTest.dispatchEventToListeners(${JSON.stringify(eventName)}, ${JSON.stringify(data)});`; this.evaluateInWebInspector(dispatchEventCodeString); }; TestPage.allowUncaughtExceptions = false; TestPage.needToSanitizeUncaughtExceptionURLs = false; TestPage.reportUncaughtException = function(message, url, lineNumber) { if (TestPage.needToSanitizeUncaughtExceptionURLs) { if (typeof url === "string") { let lastSlash = url.lastIndexOf("/"); let lastBackSlash = url.lastIndexOf("\\"); let lastPathSeparator = Math.max(lastSlash, lastBackSlash); if (lastPathSeparator > 0) url = url.substr(lastPathSeparator + 1); } } let result = `Uncaught exception in test page: ${message} [${url}:${lineNumber}]`; TestPage.addResult(result); if (!TestPage.allowUncaughtExceptions) TestPage.completeTest(); } // Catch syntax errors, type errors, and other exceptions. Run this before loading other files. window.onerror = TestPage.reportUncaughtException.bind(TestPage);