Show TOC

Upgrading from a Version Below 1.30Locate this document in the navigation structure

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.

This SAPUI5 version also contains the following upgrades:
  • 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.

Note

If you use additional open-source libraries that depend on jQuery, check whether they need to be upgraded as well.

jQuery: Dependency onjQuery Code that is Specific to Microsoft Internet Explorer 8.0 (IE8)

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: Error Handling in Synchronous XHR Calls

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

window.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);
}
jQuery: Incompatibility of jQuery.animate and sinon.fakeTimers
As jQuery 2.x only runs on browsers that support ECMAScript 5, the implementation of some helper methods have been changed and now rely on ECMAScript 5 features. One of these methods is jQuery.now which now is implemented as follows:
// 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.

QUnit: DOM Prerequisites

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.

QUnit: start() and stop() Methods

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.

QUnit: Removal of Deprecated Methods and 'window' Properties

Problem

QUnit 1.16.0 removed some deprecated methods and reduced the number of globally visible properties.
  • QUnit.raises() and window.raises no longer exist; use QUnit.throws instead.

  • Module sap/ui/test/QUnitUtils.js restores the old name and exports it to the window object as well. window.assert does no longer expose the value of QUnit.assert. Instead, each test function receives a contextualized instance of Assert which should be used to code assertions like this:
    test("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.

QUnit: Assertion Logging

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.