UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

354 lines (317 loc) 10.6 kB
/*! * OpenUI5 * (c) Copyright 2009-2021 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ /* * IMPORTANT: This is a private module, it must not be listed as a direct module dependency, * nor must it be required by code outside this package. */ /*global QUnit, sinon, */ sap.ui.define([ "sap/base/util/UriParameters", "./_utils" ], function(UriParameters, utils) { "use strict"; function makeArray(arg) { return Array.isArray(arg) ? arg : [arg]; } function requireP(deps) { return new Promise(function(resolve, reject) { sap.ui.require(makeArray(deps), function() { resolve(Array.prototype.slice.call(arguments)); }, reject); }); } function copyFiltered(target, source, filter) { if ( source ) { for ( var key in source ) { if ( Object.prototype.hasOwnProperty.call(filter, key) ) { target[key] = source[key]; } } } return target; } function ensureDOM() { function insertDIV(id) { if ( document.body.querySelector("#" + id) == null ) { var elem = document.createElement("div"); elem.id = id; document.body.insertBefore(elem, document.body.firstChild); } } return utils.whenDOMReady().then(function() { /* Prepare body: Add QUnit DOM if missing, add CSS, ... */ insertDIV("qunit"); insertDIV("qunit-fixture"); }); } function onCSPViolation(e) { var location = e.sourceFile + ":" + e.lineNumber + ":" + e.columnNumber, msg = "Security policy violation: directive '" + e.violatedDirective + "'"; if ( e.blockedURI ) { msg += " violated by '" + String(e.blockedURI).slice(0, 20) + "'"; } if ( QUnit.config.current ) { QUnit.pushFailure(msg, location); } else { // should be caught and reported by QUnit's global error handler // if not, it will only fail the current task for the securityviolationevent throw new Error(msg + " at " + location); } } /* * @const */ var QUNIT_KNOWN_OPTIONS = { altertitle: 1, collapse: 1, filter: 1, fixture: 1, hidepassed: 1, maxDepth: 1, module: 1, moduleId: 1, notrycatch: 1, noglobals: 1, seed: 1, reorder: 1, requireExpects: 1, testId: 1, testTimeout: 1, scrolltop: 1 }; function initTestModule(oConfig) { var pAfterLoader, pQUnit, pSinon, pSinonQUnitBridge, pSinonConfig, pCoverage, pTestEnv, sQUnitModule, sQUnitCSS, aJUnitDoneCallbacks; document.title = oConfig.title; // first configure the loader if needed if ( oConfig.loader ) { sap.ui.loader.config(oConfig.loader); } if ( oConfig.runAfterLoader ) { pAfterLoader = requireP( oConfig.runAfterLoader ); } else { pAfterLoader = Promise.resolve(); } if ( oConfig.qunit.version === "edge" || oConfig.qunit.version === true ) { oConfig.qunit.version = 2; } if ( typeof oConfig.qunit.version === "number" ) { if ( oConfig.qunit.version === 1 ) { sQUnitModule = "sap/ui/thirdparty/qunit"; sQUnitCSS = "sap/ui/thirdparty/qunit.css"; } else if ( oConfig.qunit.version === 2 ) { sQUnitModule = "sap/ui/thirdparty/qunit-2"; sQUnitCSS = "sap/ui/thirdparty/qunit-2.css"; } else { throw new TypeError("unsupported qunit version " + oConfig.qunit.version); } // QUnit configuration can be set in advance, we always disable the autostart window.QUnit = window.QUnit || {}; QUnit.config = QUnit.config || {}; if ( oConfig.qunit != null && typeof oConfig.qunit === 'object' ) { copyFiltered(QUnit.config, oConfig.qunit, QUNIT_KNOWN_OPTIONS); } QUnit.config.autostart = false; // now load QUnit, its CSS + the reporter bridge pQUnit = pAfterLoader.then(function() { utils.addStylesheet(sQUnitCSS); return requireP(sQUnitModule); }).then(function() { // install a mock version of the qunit-reporter-junit API to collect jUnitDone callbacks aJUnitDoneCallbacks = []; QUnit.jUnitDone = function(cb) { aJUnitDoneCallbacks.push(cb); }; return requireP("sap/ui/qunit/qunit-junit"); }).then(function() { delete QUnit.jUnitDone; return requireP("sap/ui/thirdparty/qunit-reporter-junit"); }).then(function() { // now register the collected callbacks with the real qunit-reporter-junit API aJUnitDoneCallbacks.forEach(function(cb) { QUnit.jUnitDone(cb); }); aJUnitDoneCallbacks = undefined; }); } if ( oConfig.sinon.version === "edge" || oConfig.sinon.version === true ) { oConfig.sinon.version = 4; } if ( typeof oConfig.sinon.version === "number" ) { var sinonModule, bridgeModule; if ( oConfig.sinon.version === 1 ) { sinonModule = "sap/ui/thirdparty/sinon"; bridgeModule = "sap/ui/thirdparty/sinon-qunit"; } else if ( oConfig.sinon.version === 4 ) { sinonModule = "sap/ui/thirdparty/sinon-4"; bridgeModule = "sap/ui/qunit/sinon-qunit-bridge"; } else { throw new TypeError("unsupported sinon version " + oConfig.sinon.version); } pSinon = pAfterLoader.then(function() { return requireP(sinonModule); }); if ( oConfig.sinon.qunitBridge && pQUnit ) { pSinonQUnitBridge = Promise.all([ pQUnit, pSinon ]).then(function() { return requireP(bridgeModule); }); } // sinon configuration must be applied only after sinon AND bridge have been loaded, // they both set their own defaults if ( oConfig.sinon != null && typeof oConfig.sinon === 'object' ) { pSinonConfig = Promise.all([ pSinon, pSinonQUnitBridge ]).then(function() { // copy only settings that are listed in sinon.defaultConfig sinon.config = copyFiltered(sinon.config || {}, oConfig.sinon, sinon.defaultConfig); return arguments; }); } } else if ( sQUnitModule ) { // shim dependencies for the bridges, based on the selected QUnit version // might be needed if tests load the bridge on their own sap.ui.loader.config({ shim: { "sap/ui/thirdparty/sinon-qunit": { deps: [sQUnitModule, "sap/ui/thirdparty/sinon"] }, "sap/ui/qunit/sinon-qunit-bridge": { deps: [sQUnitModule, "sap/ui/thirdparty/sinon-4"] } } }); } pCoverage = pQUnit.then(function() { if ( QUnit.urlParams.coverage ) { // when coverage has been activated in a QUnit page via checkbox, // then load blanket, configure it, then load the QUnit plugin return requireP("sap/ui/thirdparty/blanket").then(function() { if ( oConfig.coverage && window.blanket ) { if (oConfig.coverage.only != null) { window.blanket.options("sap-ui-cover-only", oConfig.coverage.only); } if (oConfig.coverage.never != null) { window.blanket.options("sap-ui-cover-never", oConfig.coverage.never); } if (oConfig.coverage.branchTracking) { window.blanket.options("branchTracking", true); } } return requireP("sap/ui/qunit/qunit-coverage"); }).then(function() { // when coverage is active, qunit-coverage sets autostart to true again QUnit.config.autostart = false; }); } else { // otherwise load only the QUnit plugin return requireP(["sap/ui/qunit/qunit-coverage"]); } }).then(function() { if ( QUnit.urlParams["sap-ui-xx-csp-policy"] ) { document.addEventListener("securitypolicyviolation", onCSPViolation); QUnit.done(function() { document.removeEventListener("securitypolicyviolation", onCSPViolation); }); } QUnit.config.urlConfig.push({ id: "sap-ui-xx-csp-policy", label: "CSP", value: { "sap-target-level-1:report-only": "Level 1", "sap-target-level-2:report-only": "Level 2" }, tooltip: "What Content-Security-Policy should the server send" }); }); pTestEnv = Promise.all([ pAfterLoader, pQUnit, pSinon, pSinonQUnitBridge, pSinonConfig, pCoverage ]); if ( oConfig.beforeBootstrap ) { pTestEnv = pTestEnv.then(function() { return requireP(oConfig.beforeBootstrap); }); } // copy UI5 configuration window["sap-ui-config"] = oConfig.ui5 || {}; if ( Array.isArray(window["sap-ui-config"].libs) ) { window["sap-ui-config"].libs = window["sap-ui-config"].libs.join(","); } if ( oConfig.bootCore ) { pTestEnv = pTestEnv.then(function() { return new Promise(function(resolve, reject) { sap.ui.require(["sap/ui/core/Core"], function(core) { core.boot(); core.attachInit(resolve); }, reject); }); }); } return pTestEnv.then(function() { if (oConfig.autostart) { // first load the tests, then ensure DOM then start tests return requireP( oConfig.module ). // Note: accepts single module or array then(function(aTestModules) { return Promise.all(aTestModules); }).then(function() { return ensureDOM(); }).then(function() { // When using xx-waitForTheme=init the test starter also // takes care of waiting for additional stylesheets e.g. caused by // implicit loading of libs via test module dependencies. // Note: config option is internally converted to lowercase if (oConfig.ui5["xx-waitfortheme"] === "init") { return new Promise(function(resolve, reject) { sap.ui.require(["sap/ui/qunit/utils/waitForThemeApplied"], resolve, reject); }).then(function(waitForThemeApplied) { return waitForThemeApplied(); }); } }).then(function() { QUnit.start(); }); } else { // first ensure the DOM then load tests as tests will start QUnit already return ensureDOM().then(function() { return requireP( oConfig.module ). // Note: accepts single module or array then(function(aTestModules) { return Promise.all(aTestModules); }); }); } }); } var oParams = UriParameters.fromQuery(window.location.search), sSuiteName = utils.getAttribute('data-sap-ui-testsuite') || oParams.get("testsuite"), sTestName = utils.getAttribute('data-sap-ui-test') || oParams.get("test"); utils.getSuiteConfig(sSuiteName).then(function(oSuiteConfig) { var oTestConfig = oSuiteConfig.tests[sTestName]; if (!oTestConfig) { throw new TypeError("Invalid test name"); } return initTestModule(oTestConfig); }).catch(function(oErr) { console.error(oErr.stack || oErr); // eslint-disable-line no-console if ( typeof QUnit !== "undefined" ) { QUnit.test("Test Starter", function() { throw oErr; }); QUnit.start(); } else { utils.whenDOMReady().then(function() { document.body.innerHTML = "<pre style='color:red;'>" + utils.encode(oErr.stack || oErr.message || String(oErr)) + "</pre>"; }); } }); });