When upgrading to the current SAPUI5 version from a version below 1.30 (released in September 2015), check whether the changes listed below influence your apps.
jQuery upgraded from version 1.11.1 to version 2.1.4
QUnit upgraded from version 1.10.0 to version 1.16.10
This upgrade may impact your SAPUI5 apps. The following sections give an overview of our findings and how to deal with them.
If you use additional open-source libraries that depend on jQuery, check whether they need to be upgraded as well.
SAPUI5 contained some code that referenced IE8-specific members of the jQuery API (like jquery.css.Hooks.opacity.set). This code has been removed.
jQuery 2.x changed the way how XMLHttpRequests (XHR) inside the jQuery.ajax call. One side-effect of this refactoring is that errors thrown in the success or error callbacks of jQuery.ajax are no longer visible for a caller of synchronous jQuery.ajax() calls. They are caught by the XHR event hooks (like onload, onerror) that jQuery uses now. Only try/catch statements inside the callbacks will catch such exceptions, but not try/catch statements outside the callbacks.
Example
#!jswindow.onerror = function(e) { alert("global error handler caught " + e); return true; } try { jQuery.ajax({ url: './nonexisting.json', async: false, dataType: 'json', success: function() { console.info("success"); }, error: function(xhr,error,status) { ^// this error will not be caught by the try/catch below, only by the global error handler above throw new Error("error fetching resource with jQuery " + jQuery.fn.jquery + ": " + xhr.status + " " + status); } }); } catch (e) { // never reached with jQuery 2, but worked with jQuery 1.11.1 alert("try-catch caught " + e.message); }
#!js// not the exact code from jQuery, but same effect jQuery.now = Date.now;
sinon.js when instructed to fakeTimers however replaces Date.now with an own version that listens to sinon.clock.tick().
This means that when jQuery is loaded before Sinon, it will keep a reference to the original Date.now function in the jQuery.now API. Therefore any code that uses jQuery.now() will not work with Sinon fake timers, or more specific, it will not react on e.g. sinon.timer.tick(xyz).
This especially affects jQuery animations and sap.ui.core.Popup that uses these animations. They won't work with sinon.fakeTimers out of the box.
To solve this, you can stub the jQuery.now() function when Sinon is used. Stub it in a way that the mocked version of Date.now is called.
Problem
QUnit changed its requirements regarding the test page. While earlier versions accepted fine-grained DOM sections for header, banner, userAgent, or tests, QUnit 1.16.0 only expects (and accepts) a single DOM hook called qunit. All details inside that DOM are managed by QUnit itself. If no DOM element with ID qunit exists, the initialization of QUnit is skipped and no tests are executed.
Solution
As short-term solution, you can use module sap/ui/test/qunit-junit.js to wrap an existing 'qunit-header' in case id='qunit' is missing.
As long-term solution, you have to migrate test pages to the suggested page content.
Problem
When methods start() and stop() are called either unbalanced (more start() than stop() calls) or when they are called outside of a test context, the test fails. Before, this was already regarded as wrong usage in earlier QUnit versions, but tests did not fail.
For example, test cases fail that unnecessarily use stop() before defining an asynchronous test with {asyncTests();.
Solution
Remove unnecessary start() and stop() calls.
Problem
QUnit.raises() and window.raises no longer exist; use QUnit.throws instead.
#!jstest("my sophisticated test", function(assert) { assert.equal("x", "u", "'x' should be an 'u'"); }
Solution
As short-term solution, you can use module sap/ui/test/qunit-junit.js to restore the old behavior.
As long-term solution, migrate to the suggested QUnit APIs.
Problem
While tests are executed, QUnit collects the result and message of each assertion and displays them to the end user. In QUnit 1.10.0 the report was created after test execution, in QUnit 1.16.0, the QUnit DOM is updated 'on the fly' while the test is running.
This means that tests that open a popup with a followOf element or, for example, use CLOSE_ON_SCROLL might run into unexpected contexts as the fixture DOM might move due to the live-logging.
Solution
The live-update cannot be suppressed. As a workaround, you can move the UIArea for the fixtureto the top of the <body> and move the QUnit reporting section (<div id='qunit'></div>) after that. Thereby, the DOM update does no longer modify the position of fixture DOM.