Skip to content

Commit

Permalink
[TASK] Migrate JavaScript unit test from karma to @web/test-runner
Browse files Browse the repository at this point in the history
The karma unit testing framework has been deprecated and
suggests to use modern alternatives instead.
We use one of the recommended alternatives named @web/test-runner
which is toolset by the modern-web.dev and open-wc.org initiatives.
It is based on mocha and es-dev-server, which allows to run our
JavaScript modules natively in the browser
(without having to bundle them via rollup).

Note that compiled test files have been removed from the
source tree, since we configure es-dev-server to transpile
them on demand, allowing error output from tests to be
using original line numbers and unmangled identifiers.

The tests are executed in chrome by default (locally and CI).
They can be executed via:

  # Run once
  npm run test

  # Run tests whenever files change
  npm run watch:build
  npm run watch:test

  # Open browser with devtools and debug mode activated
  MODE=dev npm run watch:test -- --debug

Configuration is prepared to run in other browsers via playwright.
Example:

  # https://playwright.dev/docs/browsers#install-system-dependencies
  npx playwright install --with-deps
  BROWSERS=chrome,chromium,firefox,webkit npm run test

Commands executed:

  npm remove \
    karma \
    karma-chrome-launcher \
    karma-coverage \
    karma-jasmine \
    karma-junit-reporter \
    karma-rollup-preprocessor \
    jasmine-core \
    @types/jasmine

  npm install --save-dev \
    @web/test-runner \
    @web/test-runner-playwright \
    @web/dev-server-import-maps \
    @web/dev-server-esbuild \
    @open-wc/testing \
    sinon

  git rm -rf \
    typo3/sysext/core/Tests/JavaScript \
    typo3/sysext/backend/Tests/JavaScript

  npm run build

Resolves: #101960
Releases: main, 12.4
Change-Id: Ia2fa94a9f6d66664d9fce72e7443aaeb12e0ca08
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/81040
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Benjamin Franzke <ben@bnf.dev>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benjamin Franzke <ben@bnf.dev>
Tested-by: Benni Mack <benni@typo3.org>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
  • Loading branch information
bnf committed Sep 25, 2023
1 parent d336f10 commit 169c925
Show file tree
Hide file tree
Showing 49 changed files with 3,070 additions and 1,604 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ insert_final_newline = true
trim_trailing_whitespace = true

# TS/JS-Files
[*.{ts,js}]
[*.{ts,js,mjs}]
indent_size = 2

# JSON-Files
Expand Down
9 changes: 4 additions & 5 deletions Build/Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,8 @@ module.exports = function (grunt) {

source = require('./util/map-import.js').mapImports(source, srcpath, imports);

// Workaround for https://github.com/microsoft/TypeScript/issues/35802 to avoid
// rollup from complaining in karma/jsunit test setup:
// The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten
// Workaround for https://github.com/microsoft/TypeScript/issues/35802
// > The 'this' keyword is equivalent to 'undefined' at the top level of an ES module
source = source.replace('__decorate=this&&this.__decorate||function', '__decorate=function');

return source;
Expand All @@ -320,11 +319,10 @@ module.exports = function (grunt) {
files: [{
expand: true,
cwd: '<%= paths.root %>Build/JavaScript/',
src: ['**/*.js', '**/*.js.map'],
src: ['**/*.js', '**/*.js.map', '!*/tests/**/*'],
dest: '<%= paths.sysext %>',
rename: (dest, src) => dest + src
.replace('/', '/Resources/Public/JavaScript/')
.replace('/Resources/Public/JavaScript/tests/', '/Tests/JavaScript/')
}]
},
core_icons: {
Expand Down Expand Up @@ -788,6 +786,7 @@ module.exports = function (grunt) {
expand: true,
src: [
'<%= paths.root %>Build/JavaScript/**/*.js',
'!<%= paths.root %>Build/JavaScript/*/tests/**/*',
],
dest: '<%= paths.root %>Build',
cwd: '.',
Expand Down
17 changes: 0 additions & 17 deletions Build/JSUnit/Globals.js

This file was deleted.

34 changes: 0 additions & 34 deletions Build/JSUnit/Helper.js

This file was deleted.

3 changes: 0 additions & 3 deletions Build/JSUnit/JQueryGlobal.js

This file was deleted.

4 changes: 0 additions & 4 deletions Build/JSUnit/TestSetup.js

This file was deleted.

14 changes: 0 additions & 14 deletions Build/JSUnit/karma.conf.ci.js

This file was deleted.

146 changes: 0 additions & 146 deletions Build/JSUnit/karma.conf.js

This file was deleted.

2 changes: 1 addition & 1 deletion Build/Scripts/runTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ case ${TEST_SUITE} in
SUITE_EXIT_CODE=$?
;;
unitJavascript)
COMMAND="cd Build; npm ci || exit 1; cd ..; Build/node_modules/karma/bin/karma start Build/JSUnit/karma.conf.ci.js --single-run"
COMMAND="cd Build; npm ci || exit 1; CHROME_SANDBOX=false BROWSERS=chrome npm run test"
${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name unit-javascript-${SUFFIX} -e HOME=${CORE_ROOT}/.cache ${IMAGE_NODEJS_CHROME} /bin/sh -c "${COMMAND}"
SUITE_EXIT_CODE=$?
;;
Expand Down
7 changes: 6 additions & 1 deletion Build/Sources/TypeScript/backend/document-save-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ class DocumentSaveActions {
* Initializes the save handling
*/
private initializeSaveHandling(): void {
const docHeader = document.querySelector('.t3js-module-docheader');
if (docHeader === null) {
return;
}

const elements = [
'button[form]',
'button[name^="_save"]',
Expand Down Expand Up @@ -114,7 +119,7 @@ class DocumentSaveActions {
// e.g. loading a new page
});
}, { once: true });
}).delegateTo(document.querySelector('.t3js-module-docheader'), elements);
}).delegateTo(docHeader, elements);
}

private getAttachedForm(trigger: SubmitTriggerHTMLElement): HTMLFormElement|null {
Expand Down
4 changes: 3 additions & 1 deletion Build/Sources/TypeScript/backend/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,9 @@ class Icons {
let iconsObject: Icons;
if (!iconsObject) {
iconsObject = new Icons();
TYPO3.Icons = iconsObject;
if (typeof TYPO3 !== 'undefined') {
TYPO3.Icons = iconsObject;
}
}

export default iconsObject;
6 changes: 4 additions & 2 deletions Build/Sources/TypeScript/backend/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,10 @@ try {
if (!modalObject) {
modalObject = new Modal();

// expose as global object
TYPO3.Modal = modalObject;
if (typeof TYPO3 !== 'undefined') {
// expose as global object
TYPO3.Modal = modalObject;
}
}

export default modalObject;
12 changes: 8 additions & 4 deletions Build/Sources/TypeScript/backend/module-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,11 +522,15 @@ interface ModuleMenuNamespace {
App: ModuleMenu;
}

if (!top.TYPO3.ModuleMenu) {
top.TYPO3.ModuleMenu = {
let moduleMenuApp: ModuleMenuNamespace = top?.TYPO3?.ModuleMenu;

if (!moduleMenuApp) {
moduleMenuApp = {
App: new ModuleMenu(),
};
}
if (top.TYPO3 !== undefined) {
top.TYPO3.ModuleMenu = moduleMenuApp;
}
}
const moduleMenuApp = <ModuleMenuNamespace>top.TYPO3.ModuleMenu;

export default moduleMenuApp;
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@
* The TYPO3 project - inspiring people to share!
*/

import { BackendException } from '@typo3/backend/backend-exception';
import { BackendException } from '@typo3/backend/backend-exception.js';
import { expect } from '@open-wc/testing';
import type { } from 'mocha';

describe('@typo3/backend/backend-exception', () => {
it('sets exception message', () => {
const backendException: BackendException = new BackendException('some message');
expect(backendException.message).toBe('some message');
expect(backendException.message).to.equal('some message');
});

it('sets exception code', () => {
const backendException: BackendException = new BackendException('', 12345);
expect(backendException.code).toBe(12345);
expect(backendException.code).to.equal(12345);
});
});

0 comments on commit 169c925

Please sign in to comment.