From f4ec5ad9e97351a24f5ac7d2d30593f63ce29da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Geelen=20=28sge=29?= Date: Fri, 2 Sep 2022 08:31:22 +0000 Subject: [PATCH] [IMP] web_editor: improve unit tests * Add test for the new Odoo Editor Tabs. * Refactor test utils to simplify and remove deprecated or unused features. task-2871848 Part-of: odoo/odoo#99460 --- .../editor/odoo-editor/test/editor-test.html | 31 --- .../js/editor/odoo-editor/test/editor-test.js | 44 +--- .../editor/odoo-editor/test/spec/tabs.test.js | 209 ++++++++++++++++++ .../src/js/editor/odoo-editor/test/utils.js | 7 +- addons/web_editor/views/editor.xml | 7 +- 5 files changed, 231 insertions(+), 67 deletions(-) delete mode 100644 addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.html create mode 100644 addons/web_editor/static/src/js/editor/odoo-editor/test/spec/tabs.test.js diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.html b/addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.html deleted file mode 100644 index c3e7b0cea36..00000000000 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - Odoo Editor tests - - - - - - - - - - -
-
- - diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.js index a708c96a551..af48f64d50d 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/editor-test.js @@ -9,6 +9,7 @@ import './spec/fontSize.test.js'; import './spec/format.test.js'; import './spec/insertHTML.test.js'; import './spec/fontAwesome.test.js'; +import './spec/tabs.test.js'; import './spec/autostep.test.js'; import './spec/urlRegex.test.js'; import './spec/collab.test.js'; @@ -27,40 +28,19 @@ mocha.run(failures => { ].join('\n\n'), ); } + + // Better visualisation of invisible (ZWS & TABS) character in test + // report. + const report = document.querySelector("#mocha-report"); + const allErrors = report.querySelectorAll('.test.fail .error'); + allErrors.forEach((errorEl) => { + let errorElHtml = errorEl.outerHTML + errorElHtml = errorElHtml.replaceAll('//zws//', 'zws'); + errorElHtml = errorElHtml.replaceAll('//TAB//', 'Tab'); + errorEl.outerHTML = errorElHtml; + }); } else { console.log('test successful'); } - // Clean report of successful tests to ease DEV / debug - // just add ?clean=1 - const reportEl = document.getElementById('mocha-report'); - window.scrollTo(0, window.scrollY + reportEl.getBoundingClientRect().top); - const urlParams = new URLSearchParams(window.location.search); - if (urlParams.get('clean')) { - console.log('Successful tests have been removed.'); - const report = document.querySelector("#mocha-report"); - - let hr = document.createElement("hr"); - report.prepend(hr); - let h1 = document.createElement("h1"); - h1.textContent = "Clean : Successfull tests have been removed."; - report.prepend(h1); - - const passedTests = report.querySelectorAll('.test.pass'); - for (let el of passedTests) { - el.remove(); - } - - const cleanUl = function () { - const emptyUl = report.querySelectorAll('ul:empty'); - for (let ul of emptyUl) { - ul.parentElement.remove(); - } - }; - for (let i = 4; i > 0; i--) { - cleanUl(); - } - - report.outerHTML = report.outerHTML.replaceAll('//zws//', 'zws'); - } }); diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/tabs.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/tabs.test.js new file mode 100644 index 00000000000..93325a9ad96 --- /dev/null +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/tabs.test.js @@ -0,0 +1,209 @@ +import { OdooEditor } from '../../src/OdooEditor.js'; +import { + BasicEditor, + deleteBackward, + deleteForward, + insertText, + triggerEvent, + redo, + testEditor, + undo, +} from '../utils.js'; + +describe('Tabs', () => { + const oeTab = (size = '40px', contenteditable = true) => { + return `\u0009\u200B` + }; + describe('insert Tabulation', () => { + it('should insert a tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a[]b

`, + stepFunction: async editor => { + await triggerEvent(editor.editable, 'keydown', { key: 'Tab'}); + }, + contentAfterEdit: `

a${oeTab('32.8906px', false)}[]b

`, + contentAfter: `

a${oeTab('32.8906px')}[]b

`, + }); + }); + it('should clear selection and insert a tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a[xxx]b

`, + stepFunction: async editor => { + await triggerEvent(editor.editable, 'keydown', { key: 'Tab'}); + }, + contentAfterEdit: `

a${oeTab('32.8906px', false)}[]b

`, + contentAfter: `

a${oeTab('32.8906px')}[]b

`, + }); + }); + it('should insert two tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a[]b

`, + stepFunction: async editor => { + await triggerEvent(editor.editable, 'keydown', { key: 'Tab'}); + await triggerEvent(editor.editable, 'keydown', { key: 'Tab'}); + }, + contentAfterEdit: `

a${oeTab('32.8906px', false)}${oeTab('40px', false)}[]b

`, + contentAfter: `

a${oeTab('32.8906px')}${oeTab()}[]b

`, + }); + }); + it('should insert two tab character with one char between', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a[]b

`, + stepFunction: async editor => { + await triggerEvent(editor.editable, 'keydown', { key: 'Tab'}); + await insertText(editor,'a'); + await triggerEvent(editor.editable, 'keydown', { key: 'Tab'}); + }, + contentAfterEdit: `

a${oeTab('32.8906px', false)}a${oeTab('32.8906px', false)}[]b

`, + contentAfter: `

a${oeTab('32.8906px')}a${oeTab('32.8906px')}[]b

`, + }); + }); + }); + describe('delete backward Tabulation', () => { + it('should remove one tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}[]b

`, + stepFunction: async editor => { + await deleteBackward(editor); + }, + contentAfter: `

a[]b

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}[]${oeTab()}b

`, + stepFunction: async editor => { + await deleteBackward(editor); + }, + contentAfter: `

a[]${oeTab('32.8906px')}b

`, + }); + }); + it('should remove two tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}${oeTab()}[]b

`, + stepFunction: async editor => { + await deleteBackward(editor); + await deleteBackward(editor); + }, + contentAfter: `

a[]b

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}${oeTab()}[]${oeTab()}b

`, + stepFunction: async editor => { + await deleteBackward(editor); + await deleteBackward(editor); + }, + contentAfter: `

a[]${oeTab('32.8906px')}b

`, + }); + }); + it('should remove three tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}${oeTab()}${oeTab()}[]b

`, + stepFunction: async editor => { + await deleteBackward(editor); + await deleteBackward(editor); + await deleteBackward(editor); + }, + contentAfter: `

a[]b

`, + }); + }); + }); + describe('delete forward Tabulation', () => { + it('should remove one tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a[]${oeTab('32.8906px')}b1

`, + stepFunction: async editor => { + await deleteForward(editor); + }, + contentAfter: `

a[]b1

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}[]${oeTab()}b2

`, + stepFunction: async editor => { + await deleteForward(editor); + }, + contentAfter: `

a${oeTab('32.8906px')}[]b2

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a[]${oeTab('32.8906px')}${oeTab()}b3

`, + stepFunction: async editor => { + await deleteForward(editor); + }, + contentAfter: `

a[]${oeTab('32.8906px')}b3

`, + }); + }); + it('should remove two tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a[]${oeTab('32.8906px')}${oeTab()}b1

`, + stepFunction: async editor => { + await deleteForward(editor); + await deleteForward(editor); + }, + contentAfter: `

a[]b1

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a[]${oeTab('32.8906px')}${oeTab()}${oeTab()}b2

`, + stepFunction: async editor => { + await deleteForward(editor); + await deleteForward(editor); + }, + contentAfter: `

a[]${oeTab('32.8906px')}b2

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}[]${oeTab()}${oeTab()}b3

`, + stepFunction: async editor => { + await deleteForward(editor); + await deleteForward(editor); + }, + contentAfter: `

a${oeTab('32.8906px')}[]b3

`, + }); + }); + it('should remove three tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a[]${oeTab('32.8906px')}${oeTab()}${oeTab()}b

`, + stepFunction: async editor => { + await deleteForward(editor); + await deleteForward(editor); + await deleteForward(editor); + }, + contentAfter: `

a[]b

`, + }); + }); + }); + describe('delete mixxed Tabulation', () => { + it('should remove all tab character', async () => { + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}[]${oeTab()}b1

`, + stepFunction: async editor => { + await deleteForward(editor); + await deleteBackward(editor); + }, + contentAfter: `

a[]b1

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}[]${oeTab()}b2

`, + stepFunction: async editor => { + await deleteBackward(editor); + await deleteForward(editor); + }, + contentAfter: `

a[]b2

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}${oeTab()}[]${oeTab()}b3

`, + stepFunction: async editor => { + await deleteBackward(editor); + await deleteForward(editor); + await deleteBackward(editor); + }, + contentAfter: `

a[]b3

`, + }); + await testEditor(BasicEditor, { + contentBefore: `

a${oeTab('32.8906px')}[]${oeTab()}${oeTab()}b4

`, + stepFunction: async editor => { + await deleteForward(editor); + await deleteBackward(editor); + await deleteForward(editor); + }, + contentAfter: `

a[]b4

`, + }); + }); + }); +}); diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/utils.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/utils.js index a29a988c99c..ef5b4d8ea0c 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/utils.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/utils.js @@ -264,8 +264,11 @@ export function renderTextualSelection() { */ export function customErrorMessage(assertLocation, value, expected) { const zws = '//zws//'; - value = value.replace('\u200B', zws); - expected = expected.replace('\u200B', zws); + value = value.replaceAll('\u200B', zws); + expected = expected.replaceAll('\u200B', zws); + const tab = '//TAB//'; + value = value.replaceAll('\u0009', tab); + expected = expected.replaceAll('\u0009', tab); return `[${assertLocation}]\nactual : '${value}'\nexpected: '${expected}'\n\nStackTrace `; } diff --git a/addons/web_editor/views/editor.xml b/addons/web_editor/views/editor.xml index 8b1ca8078d2..8fa05b0a832 100644 --- a/addons/web_editor/views/editor.xml +++ b/addons/web_editor/views/editor.xml @@ -175,14 +175,17 @@