
"The node:test module facilitates the creation of JavaScript tests."
https://nodejs.org/api/test.html
"type": "module",
"scripts": {
...
"test:nodejs" : "node --test webapp/test/unit-node"
}
$ npm install --save-dev happy-dom
import { describe, it, before, beforeEach, after, afterEach, mock } from 'node:test';
import assert from 'node:assert';
import { Window } from 'happy-dom';
describe('test suite happyDOM', function () {
let window = {};
let sap = {};
before(async () => {
//Start Happy DOM
window = new Window({ url: 'http://localhost:8080/' });
});
describe('Test happyDOM', async function () {
it('test if happyDOM has been loaded', function () {
assert.ok(window);
assert.ok(window.document);
assert.ok(window.document.body);
});
});
before(async () => {
//Start Happy DOM
window = new Window({ url: 'http://localhost:8080/' });
// Patch window.performance.timing because it doesn't exist in nodejs nor happyDOM
window.performance.timing = {
fetchStart: Date.now(),
navigationStart: Date.now()
};
const scriptUi5Bootstrap = window.document.createElement('script');
scriptUi5Bootstrap.id = "sap-ui-bootstrap";
scriptUi5Bootstrap.src = "https://ui5.sap.com/resources/sap-ui-core.js";
scriptUi5Bootstrap.setAttribute('data-sap-ui-libs', "sap.m");
scriptUi5Bootstrap.setAttribute('data-sap-ui-compatVersion', "edge");
scriptUi5Bootstrap.setAttribute('data-sap-ui-async', "true");
scriptUi5Bootstrap.setAttribute('data-sap-ui-language', "en");
scriptUi5Bootstrap.setAttribute('data-sap-ui-resourceRoots', '{"sap.ui.demo.todo" : "../../"}');
scriptUi5Bootstrap.crossorigin = "anonymous";
window.document.body.appendChild(scriptUi5Bootstrap);
await window.happyDOM.whenAsyncComplete();
await new Promise((resolve, reject) => {
sap = window.sap;
sap.ui.require([
"sap/ui/demo/todo/controller/App.controller"
], function () {
resolve();
}, function (err) {
reject(err);
});
});
});
it('test if UI5 has been loaded', function () {
assert.ok(sap);
assert.ok(sap.ui.demo.todo.controller.App);
});
describe('Test init state', async function () {
beforeEach((context) => {
context.oAppController = new sap.ui.demo.todo.controller.App();
context.oViewStub = new sap.ui.base.ManagedObject({});
context.oJSONModelStub = new sap.ui.model.json.JSONModel({
todos: []
});
mock.method(sap.ui.core.mvc.Controller.prototype, "getView", () => context.oViewStub);
context.oViewStub.setModel(context.oJSONModelStub);
});
afterEach(() => {
mock.reset();
});
it('Check controller initial state', (context) => {
// Act
context.oAppController.onInit();
// Assert
assert.deepEqual(context.oAppController.aSearchFilters, [], "Search filters have been instantiated empty");
assert.deepEqual(context.oAppController.aTabFilters, [], "Tab filters have been instantiated empty");
var oModel = context.oAppController.getView().getModel("view").getData();
assert.deepEqual(oModel, { isMobile: sap.ui.Device.browser.mobile, filterText: undefined });
});
});
import { describe, it, before, beforeEach, after, afterEach, mock } from 'node:test';
import assert from 'node:assert';
import { Window } from 'happy-dom';
describe('test suite happyDOM', function () {
let window = {};
let sap = {};
before(async () => {
//Start Happy DOM
window = new Window({ url: 'http://localhost:8080/' });
// Patch window.performance.timing because it doesn't exist in nodejs nor happyDOM
window.performance.timing = {
fetchStart: Date.now(),
navigationStart: Date.now()
};
const scriptUi5Bootstrap = window.document.createElement('script');
scriptUi5Bootstrap.id = "sap-ui-bootstrap";
scriptUi5Bootstrap.src = "https://ui5.sap.com/resources/sap-ui-core.js";
scriptUi5Bootstrap.setAttribute('data-sap-ui-libs', "sap.m");
scriptUi5Bootstrap.setAttribute('data-sap-ui-compatVersion', "edge");
scriptUi5Bootstrap.setAttribute('data-sap-ui-async', "true");
scriptUi5Bootstrap.setAttribute('data-sap-ui-language', "en");
scriptUi5Bootstrap.setAttribute('data-sap-ui-resourceRoots', '{"sap.ui.demo.todo" : "../../"}');
scriptUi5Bootstrap.crossorigin = "anonymous";
window.document.body.appendChild(scriptUi5Bootstrap);
await window.happyDOM.whenAsyncComplete();
await new Promise((resolve, reject) => {
sap = window.sap;
sap.ui.require([
"sap/ui/demo/todo/controller/App.controller"
], function () {
resolve();
}, function (err) {
reject(err);
});
});
});
describe('Test happyDOM', async function () {
it('test if happyDOM has been loaded', function () {
assert.ok(window);
assert.ok(window.document);
assert.ok(window.document.body);
});
it('test if UI5 has been loaded', function () {
assert.ok(sap);
assert.ok(sap.ui.demo.todo.controller.App);
});
});
describe('Test init state', async function () {
beforeEach((context) => {
context.oAppController = new sap.ui.demo.todo.controller.App();
context.oViewStub = new sap.ui.base.ManagedObject({});
context.oJSONModelStub = new sap.ui.model.json.JSONModel({
todos: []
});
mock.method(sap.ui.core.mvc.Controller.prototype, "getView", () => context.oViewStub);
context.oViewStub.setModel(context.oJSONModelStub);
});
afterEach(() => {
mock.reset();
});
it('Check controller initial state', (context) => {
// Act
context.oAppController.onInit();
// Assert
assert.deepEqual(context.oAppController.aSearchFilters, [], "Search filters have been instantiated empty");
assert.deepEqual(context.oAppController.aTabFilters, [], "Tab filters have been instantiated empty");
var oModel = context.oAppController.getView().getModel("view").getData();
assert.deepEqual(oModel, { isMobile: sap.ui.Device.browser.mobile, filterText: undefined });
});
});
});
$ npm install --save-dev jsdom
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenUI5 Todo App</title>
</head>
<body class="sapUiBody">
<script id="sap-ui-bootstrap" src="https://ui5.sap.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m"
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true"
data-sap-ui-language="en"
data-sap-ui-oninit="onUi5Boot()"
data-sap-ui-resourceRoots='{
"sap.ui.demo.todo": "../"
}' crossorigin="anonymous">
</script>
<script>
function onUi5Boot() {
sap.ui.require([
"sap/ui/demo/todo/controller/App.controller",
], function () {
if (window.onUi5ModulesLoaded) {
window.onUi5ModulesLoaded();
}
});
}
</script>
</body>
</html>
import { describe, it, before, beforeEach, after, afterEach, mock } from 'node:test';
import assert from 'node:assert';
import { JSDOM } from 'jsdom';
function buildFromFile() {
const options = {
resources: 'usable',
referrer: "https://ui5.sap.com/",
runScripts: 'dangerously',
pretendToBeVisual: true,
beforeParse: (jsdomWindow) => {
// Patch window.matchMedia because it doesn't exist in JSDOM
jsdomWindow.matchMedia = function () {
return {
matches: false,
addListener: function () { },
removeListener: function () { }
};
};
// Patch window.performance.timing because it doesn't exist in nodejs nor JSDOM
jsdomWindow.performance.timing = {
fetchStart: Date.now(),
navigationStart: Date.now(),
};
}
};
return JSDOM.fromFile('webapp/test/test-jsdom.html', options);
};
describe('test suite JSDOM', function () {
let dom = {};
let window = {};
let sap = {};
before(async () => {
dom = await buildFromFile();
window = dom.window;
await new Promise((resolve) => {
window.onUi5ModulesLoaded = () => {
sap = window.sap;
resolve();
};
});
});
after(() => {
window.close();
});
describe('Test JSDOM', async function () {
it('test if JSDOM has been loaded', function () {
assert.ok(window);
assert.ok(window.document);
assert.ok(window.document.body);
});
it('test if UI5 has been loaded', function () {
assert.ok(sap);
assert.ok(sap.ui.demo.todo.controller.App);
});
});
});
import { describe, it, before, beforeEach, after, afterEach, mock } from 'node:test';
import assert from 'node:assert';
import { JSDOM } from 'jsdom';
function buildFromFile() {
const options = {
resources: 'usable',
referrer: "https://ui5.sap.com/",
runScripts: 'dangerously',
pretendToBeVisual: true,
beforeParse: (jsdomWindow) => {
// Patch window.matchMedia because it doesn't exist in JSDOM
jsdomWindow.matchMedia = function () {
return {
matches: false,
addListener: function () { },
removeListener: function () { }
};
};
// Patch window.performance.timing because it doesn't exist in nodejs nor JSDOM
jsdomWindow.performance.timing = {
fetchStart: Date.now(),
navigationStart: Date.now(),
};
}
};
return JSDOM.fromFile('webapp/test/test-jsdom.html', options);
};
describe('test suite JSDOM', function () {
let dom = {};
let window = {};
let sap = {};
before(async () => {
dom = await buildFromFile();
window = dom.window;
await new Promise((resolve) => {
window.onUi5ModulesLoaded = () => {
sap = window.sap;
resolve();
};
});
});
after(() => {
window.close();
});
describe('Test JSDOM', async function () {
it('test if JSDOM has been loaded', function () {
assert.ok(window);
assert.ok(window.document);
assert.ok(window.document.body);
});
it('test if UI5 has been loaded', function () {
assert.ok(sap);
assert.ok(sap.ui.demo.todo.controller.App);
});
});
describe('Test init state', async function () {
beforeEach((context) => {
context.oAppController = new sap.ui.demo.todo.controller.App();
context.oViewStub = new sap.ui.base.ManagedObject({});
context.oJSONModelStub = new sap.ui.model.json.JSONModel({
todos: []
});
mock.method(sap.ui.core.mvc.Controller.prototype, "getView", () => context.oViewStub);
context.oViewStub.setModel(context.oJSONModelStub);
});
afterEach(() => {
mock.reset();
});
it('Check controller initial state', (context) => {
// Act
context.oAppController.onInit();
// Assert
assert.deepEqual(context.oAppController.aSearchFilters, [], "Search filters have been instantiated empty");
assert.deepEqual(context.oAppController.aTabFilters, [], "Tab filters have been instantiated empty");
var oModel = context.oAppController.getView().getModel("view").getData();
assert.deepEqual(oModel, { isMobile: sap.ui.Device.browser.mobile, filterText: undefined });
});
});
});
$ npm run test:nodejs
"scripts": {
...
"test:nodejs:coverage": "node --test --experimental-test-coverage webapp/test/unit-node-test-runner"
}
$ npm run test:nodejs:coverage
Node Test Runner results with code coverage
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
7 | |
7 | |
7 | |
6 | |
4 | |
4 | |
4 | |
4 | |
4 | |
3 |