"A blazing fast unit test framework powered by Vite."
https://vitest.dev
$ npm install --save-dev vitest
"type": "module",
"scripts": {
...
"test:nodejs" : "vitest run"
}
$ npm install --save-dev happy-dom
/**
* @vitest-environment happy-dom
*/
import { describe, it, beforeAll, beforeEach, afterAll, afterEach, expect, vi } from 'vitest';
describe('test suite happyDOM', function () {
let sap = {};
describe('Test happyDOM', function () {
it('test if happyDOM has been loaded', function () {
expect(window).toBeTruthy();
expect(document).toBeTruthy();
expect(document.body).toBeTruthy();
});
});
});
beforeAll(async () => {
//Mocking deprecated and not available window.performance.timing
window.performance.timing = {
fetchStart: Date.now(),
navigationStart: Date.now()
};
//Script tag to bootstrap UI5
window.happyDOM.setURL('http://localhost:8080/');
const scriptUi5Bootstrap = 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";
document.body.appendChild(scriptUi5Bootstrap);
//Await UI5 to load, then use sap.ui.require to load your own UI5 files
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 () {
expect(sap).toBeTruthy();
expect(sap.ui.demo.todo.controller.App).toBeTruthy();
});
describe('Test init state', 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: []
});
vi.spyOn(sap.ui.core.mvc.Controller.prototype, 'getView').mockReturnValue(context.oViewStub);
context.oViewStub.setModel(context.oJSONModelStub);
});
afterEach(() => {
vi.clearAllMocks();
});
it('Check controller initial state', (context) => {
// Act
context.oAppController.onInit();
// Assert
expect(context.oAppController.aSearchFilters).toEqual([]); //"Search filters have been instantiated empty"
expect(context.oAppController.aTabFilters).toEqual([]); //"Tab filters have been instantiated empty"
var oModel = context.oAppController.getView().getModel("view").getData();
expect(oModel).toEqual({ isMobile: sap.ui.Device.browser.mobile, filterText: undefined });
});
});
/**
* @vitest-environment happy-dom
*/
import { describe, it, beforeAll, beforeEach, afterAll, afterEach, expect, vi } from 'vitest';
describe('test suite happyDOM', function () {
let sap = {};
beforeAll(async () => {
//Mocking deprecated and not available window.performance.timing
window.performance.timing = {
fetchStart: Date.now(),
navigationStart: Date.now()
};
//Script tag to bootstrap UI5
window.happyDOM.setURL('http://localhost:8080/');
const scriptUi5Bootstrap = 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";
document.body.appendChild(scriptUi5Bootstrap);
//Await UI5 to load, then use sap.ui.require to load your own UI5 files
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', function () {
it('test if happyDOM has been loaded', function () {
expect(window).toBeTruthy();
expect(document).toBeTruthy();
expect(document.body).toBeTruthy();
});
it('test if UI5 has been loaded', function () {
expect(sap).toBeTruthy();
expect(sap.ui.demo.todo.controller.App).toBeTruthy();
});
});
describe('Test init state', 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: []
});
vi.spyOn(sap.ui.core.mvc.Controller.prototype, 'getView').mockReturnValue(context.oViewStub);
context.oViewStub.setModel(context.oJSONModelStub);
});
afterEach(() => {
vi.clearAllMocks();
});
it('Check controller initial state', (context) => {
// Act
context.oAppController.onInit();
// Assert
expect(context.oAppController.aSearchFilters).toEqual([]); //"Search filters have been instantiated empty"
expect(context.oAppController.aTabFilters).toEqual([]); //"Tab filters have been instantiated empty"
var oModel = context.oAppController.getView().getModel("view").getData();
expect(oModel).toEqual({ 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>
/**
* @vitest-environment node
*/
import { describe, it, beforeAll, beforeEach, afterAll, afterEach, expect, vi } from 'vitest';
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 = {};
beforeAll(async () => {
dom = await buildFromFile();
window = dom.window;
await new Promise((resolve) => {
window.onUi5ModulesLoaded = () => {
sap = window.sap;
resolve();
};
});
});
afterAll(() => {
window.close();
});
describe('Test JSDOM', function () {
it('test if JSDOM has been loaded', function () {
expect(window).toBeTruthy();
expect(window.document).toBeTruthy();
expect(window.document.body).toBeTruthy();
});
it('test if UI5 has been loaded', function () {
expect(sap).toBeTruthy();
expect(sap.ui.demo.todo.controller.App).toBeTruthy();
});
});
});
/**
* @vitest-environment node
*/
import { describe, it, beforeAll, beforeEach, afterAll, afterEach, expect, vi } from 'vitest';
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 = {};
beforeAll(async () => {
dom = await buildFromFile();
window = dom.window;
await new Promise((resolve) => {
window.onUi5ModulesLoaded = () => {
sap = window.sap;
resolve();
};
});
});
afterAll(() => {
window.close();
});
describe('Test JSDOM', function () {
it('test if JSDOM has been loaded', function () {
expect(window).toBeTruthy();
expect(window.document).toBeTruthy();
expect(window.document.body).toBeTruthy();
});
it('test if UI5 has been loaded', function () {
expect(sap).toBeTruthy();
expect(sap.ui.demo.todo.controller.App).toBeTruthy();
});
});
describe('Test init state', 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: []
});
vi.spyOn(sap.ui.core.mvc.Controller.prototype, 'getView').mockReturnValue(context.oViewStub);
context.oViewStub.setModel(context.oJSONModelStub);
});
afterEach(() => {
vi.clearAllMocks();
});
it('Check controller initial state', (context) => {
// Act
context.oAppController.onInit();
// Assert
expect(context.oAppController.aSearchFilters).toEqual([]); //"Search filters have been instantiated empty"
expect(context.oAppController.aTabFilters).toEqual([]); //"Tab filters have been instantiated empty"
var oModel = context.oAppController.getView().getModel("view").getData();
expect(oModel).toEqual({ isMobile: sap.ui.Device.browser.mobile, filterText: undefined });
});
});
});
$ npm run test:nodejs
"scripts": {
...
"test:nodejs:coverage": "vitest run --coverage"
}
$ npm install --save-dev @vitest/coverage-v8
$ npm run test:nodejs: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 |
---|---|
19 | |
10 | |
8 | |
5 | |
4 | |
4 | |
3 | |
3 | |
2 | |
2 |