[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
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||
<link rel="icon" href="../demo/favicon.ico" />
|
||||
|
||||
<title>Odoo Editor tests</title>
|
||||
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<style type="text/css">
|
||||
b.zws {
|
||||
background-color: #c00;
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
padding: 1px 3px;
|
||||
font-size: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
<script src="../../../../../lib/DomPurify.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
<script src="lib/chai.js"></script>
|
||||
<script>mocha.setup('bdd').fullTrace()</script>
|
||||
<script src="./editor-test.js" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<div id="editor-test-container"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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//', '<b class="zws">zws</b>');
|
||||
errorElHtml = errorElHtml.replaceAll('//TAB//', '<b class="tab">Tab</b>');
|
||||
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//', '<b class="zws">zws</b>');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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 `<span class="oe-tabs"${contenteditable ? '' : ' contenteditable="false"'} style="width: ${size};">\u0009</span>\u200B`
|
||||
};
|
||||
describe('insert Tabulation', () => {
|
||||
it('should insert a tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await triggerEvent(editor.editable, 'keydown', { key: 'Tab'});
|
||||
},
|
||||
contentAfterEdit: `<p>a${oeTab('32.8906px', false)}[]b</p>`,
|
||||
contentAfter: `<p>a${oeTab('32.8906px')}[]b</p>`,
|
||||
});
|
||||
});
|
||||
it('should clear selection and insert a tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[xxx]b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await triggerEvent(editor.editable, 'keydown', { key: 'Tab'});
|
||||
},
|
||||
contentAfterEdit: `<p>a${oeTab('32.8906px', false)}[]b</p>`,
|
||||
contentAfter: `<p>a${oeTab('32.8906px')}[]b</p>`,
|
||||
});
|
||||
});
|
||||
it('should insert two tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await triggerEvent(editor.editable, 'keydown', { key: 'Tab'});
|
||||
await triggerEvent(editor.editable, 'keydown', { key: 'Tab'});
|
||||
},
|
||||
contentAfterEdit: `<p>a${oeTab('32.8906px', false)}${oeTab('40px', false)}[]b</p>`,
|
||||
contentAfter: `<p>a${oeTab('32.8906px')}${oeTab()}[]b</p>`,
|
||||
});
|
||||
});
|
||||
it('should insert two tab character with one char between', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await triggerEvent(editor.editable, 'keydown', { key: 'Tab'});
|
||||
await insertText(editor,'a');
|
||||
await triggerEvent(editor.editable, 'keydown', { key: 'Tab'});
|
||||
},
|
||||
contentAfterEdit: `<p>a${oeTab('32.8906px', false)}a${oeTab('32.8906px', false)}[]b</p>`,
|
||||
contentAfter: `<p>a${oeTab('32.8906px')}a${oeTab('32.8906px')}[]b</p>`,
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('delete backward Tabulation', () => {
|
||||
it('should remove one tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}[]b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteBackward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}[]${oeTab()}b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteBackward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]${oeTab('32.8906px')}b</p>`,
|
||||
});
|
||||
});
|
||||
it('should remove two tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}${oeTab()}[]b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteBackward(editor);
|
||||
await deleteBackward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}${oeTab()}[]${oeTab()}b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteBackward(editor);
|
||||
await deleteBackward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]${oeTab('32.8906px')}b</p>`,
|
||||
});
|
||||
});
|
||||
it('should remove three tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}${oeTab()}${oeTab()}[]b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteBackward(editor);
|
||||
await deleteBackward(editor);
|
||||
await deleteBackward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b</p>`,
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('delete forward Tabulation', () => {
|
||||
it('should remove one tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]${oeTab('32.8906px')}b1</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b1</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}[]${oeTab()}b2</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a${oeTab('32.8906px')}[]b2</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]${oeTab('32.8906px')}${oeTab()}b3</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]${oeTab('32.8906px')}b3</p>`,
|
||||
});
|
||||
});
|
||||
it('should remove two tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]${oeTab('32.8906px')}${oeTab()}b1</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b1</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]${oeTab('32.8906px')}${oeTab()}${oeTab()}b2</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]${oeTab('32.8906px')}b2</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}[]${oeTab()}${oeTab()}b3</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a${oeTab('32.8906px')}[]b3</p>`,
|
||||
});
|
||||
});
|
||||
it('should remove three tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a[]${oeTab('32.8906px')}${oeTab()}${oeTab()}b</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
await deleteForward(editor);
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b</p>`,
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('delete mixxed Tabulation', () => {
|
||||
it('should remove all tab character', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}[]${oeTab()}b1</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
await deleteBackward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b1</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}[]${oeTab()}b2</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteBackward(editor);
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b2</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}${oeTab()}[]${oeTab()}b3</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteBackward(editor);
|
||||
await deleteForward(editor);
|
||||
await deleteBackward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b3</p>`,
|
||||
});
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: `<p>a${oeTab('32.8906px')}[]${oeTab()}${oeTab()}b4</p>`,
|
||||
stepFunction: async editor => {
|
||||
await deleteForward(editor);
|
||||
await deleteBackward(editor);
|
||||
await deleteForward(editor);
|
||||
},
|
||||
contentAfter: `<p>a[]b4</p>`,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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 `;
|
||||
}
|
||||
|
||||
@@ -175,14 +175,17 @@
|
||||
<t t-call-assets="web_editor.assets_tests_styles" t-js="false"/>
|
||||
<link rel="stylesheet" href="/web_editor/static/src/js/editor/odoo-editor/test/lib/mocha.css"/>
|
||||
<style type="text/css">
|
||||
b.zws {
|
||||
background-color: #c00;
|
||||
#mocha-report b.zws, #mocha-report b.tab {
|
||||
background-color: #833112;
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
padding: 1px 3px;
|
||||
font-size: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#mocha-report b.tab {
|
||||
background-color: #14386e;
|
||||
}
|
||||
</style>
|
||||
<script src="/web_editor/static/lib/DOMPurify.js"></script>
|
||||
<script src="/web_editor/static/src/js/editor/odoo-editor/test/lib/mocha.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user