[ADD] web_editor: add tests for Powerbox
This adds a series of tests for the editor's Powerbox and its integration with the editor. closes odoo/odoo#96287 Related: odoo/enterprise#29649 Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import './spec/fontAwesome.test.js';
|
||||
import './spec/autostep.test.js';
|
||||
import './spec/urlRegex.test.js';
|
||||
import './spec/collab.test.js';
|
||||
import './spec/powerbox.test.js';
|
||||
/* global mocha */
|
||||
|
||||
mocha.run(failures => {
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
import { setSelection } from '../../src/OdooEditor.js';
|
||||
import { Powerbox } from '../../src/powerbox/Powerbox.js';
|
||||
import { BasicEditor, insertText, testEditor, triggerEvent } from '../utils.js';
|
||||
|
||||
const getCurrentCommandNames = powerbox => {
|
||||
return [...powerbox.el.querySelectorAll('.oe-powerbox-commandName')].map(c => c.innerText);
|
||||
}
|
||||
|
||||
describe('Powerbox', () => {
|
||||
describe('integration', () => {
|
||||
it('should open the Powerbox on type `/`', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: '<p>ab[]</p>',
|
||||
stepFunction: async editor => {
|
||||
window.chai.expect(editor.powerbox.isOpen).to.eql(false);
|
||||
window.chai.expect(editor.powerbox.el.style.display).to.eql('none');
|
||||
await insertText(editor, '/');
|
||||
window.chai.expect(editor.powerbox.isOpen).to.eql(true);
|
||||
window.chai.expect(editor.powerbox.el.style.display).not.to.eql('none');
|
||||
},
|
||||
});
|
||||
});
|
||||
it('should filter the Powerbox contents with term', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: '<p>ab[]</p>',
|
||||
stepFunction: async editor => {
|
||||
await insertText(editor, '/');
|
||||
await insertText(editor, 'head');
|
||||
triggerEvent(editor.editable, 'keyup');
|
||||
window.chai.expect(getCurrentCommandNames(editor.powerbox)).to.eql(['Heading 1', 'Heading 2', 'Heading 3']);
|
||||
},
|
||||
});
|
||||
});
|
||||
it('should execute command and remove term and hot character on Enter', async () => {
|
||||
await testEditor(BasicEditor, {
|
||||
contentBefore: '<p>ab[]</p>',
|
||||
stepFunction: async editor => {
|
||||
editor.powerbox.el.classList.add('yo');
|
||||
await insertText(editor, '/');
|
||||
await insertText(editor, 'head');
|
||||
triggerEvent(editor.editable, 'keyup');
|
||||
triggerEvent(editor.editable, 'keydown', { key: 'Enter' });
|
||||
},
|
||||
contentAfter: '<h1>ab[]</h1>',
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('class', () => {
|
||||
it('should properly order default commands and categories', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
const powerbox = new Powerbox({
|
||||
categories: [
|
||||
{name: 'a', priority: 2},
|
||||
{name: 'b', priority: 4},
|
||||
{name: 'c', priority: 1}, // redefined lower -> ignore
|
||||
{name: 'd', priority: 4}, // same as b -> alphabetical
|
||||
{name: 'c', priority: 3},
|
||||
],
|
||||
commands: [
|
||||
{category: 'f', name: 'f1'}, // category doesn't exist -> end
|
||||
{category: 'e', name: 'e1'}, // category doesn't exist -> end
|
||||
{category: 'a', name: 'a1', priority: 1},
|
||||
{category: 'a', name: 'a4', priority: 3},
|
||||
{category: 'a', name: 'a2', priority: 3},
|
||||
{category: 'a', name: 'a3', priority: 2},
|
||||
{category: 'b', name: 'b3'}, // no priority -> priority 1
|
||||
{category: 'b', name: 'b1'},
|
||||
{category: 'b', name: 'b2'},
|
||||
{category: 'c', name: 'c1'},
|
||||
{category: 'd', name: 'd1'},
|
||||
],
|
||||
editable,
|
||||
});
|
||||
powerbox.open();
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(
|
||||
['b1', 'b2', 'b3', 'd1', 'c1', 'a2', 'a4', 'a3', 'a1', 'e1', 'f1']
|
||||
);
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
it('should navigate through commands with arrow keys', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
const powerbox = new Powerbox({
|
||||
categories: [],
|
||||
commands: [
|
||||
{category: 'a', name: '2'},
|
||||
{category: 'a', name: '3'},
|
||||
{category: 'a', name: '1'},
|
||||
],
|
||||
editable,
|
||||
});
|
||||
powerbox.open();
|
||||
window.chai.expect(powerbox._context.selectedCommand.name).to.eql('1');
|
||||
triggerEvent(editable, 'keydown', { key: 'ArrowDown'});
|
||||
window.chai.expect(powerbox._context.selectedCommand.name).to.eql('2');
|
||||
triggerEvent(editable, 'keydown', { key: 'ArrowDown'});
|
||||
window.chai.expect(powerbox._context.selectedCommand.name).to.eql('3');
|
||||
triggerEvent(editable, 'keydown', { key: 'ArrowUp'});
|
||||
window.chai.expect(powerbox._context.selectedCommand.name).to.eql('2');
|
||||
triggerEvent(editable, 'keydown', { key: 'ArrowUp'});
|
||||
window.chai.expect(powerbox._context.selectedCommand.name).to.eql('1');
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
it('should execute command on press Enter', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
const powerbox = new Powerbox({
|
||||
categories: [],
|
||||
commands: [
|
||||
{category: 'a', name: '2', callback: () => editable.innerText = '2'},
|
||||
{category: 'a', name: '3', callback: () => editable.innerText = '3'},
|
||||
{category: 'a', name: '1', callback: () => editable.innerText = '1'},
|
||||
],
|
||||
editable,
|
||||
});
|
||||
powerbox.open();
|
||||
window.chai.expect(editable.innerText).to.eql('');
|
||||
triggerEvent(editable, 'keydown', { key: 'Enter'});
|
||||
window.chai.expect(editable.innerText).to.eql('1');
|
||||
triggerEvent(editable, 'keydown', { key: 'ArrowDown'});
|
||||
triggerEvent(editable, 'keydown', { key: 'Enter'});
|
||||
window.chai.expect(editable.innerText).to.eql('2');
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
it('should filter commands with `commandFilters`', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
const powerbox = new Powerbox({
|
||||
categories: [],
|
||||
commands: [
|
||||
{category: 'a', name: 'a2'},
|
||||
{category: 'a', name: 'a3'},
|
||||
{category: 'a', name: 'a1'},
|
||||
{category: 'b', name: 'b2x'},
|
||||
{category: 'b', name: 'b3x'},
|
||||
{category: 'b', name: 'b1y'},
|
||||
],
|
||||
editable,
|
||||
commandFilters: [commands => commands.filter(command => command.category === 'b')],
|
||||
});
|
||||
powerbox.open();
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['b1y', 'b2x', 'b3x']);
|
||||
powerbox.close();
|
||||
powerbox.commandFilters.push(commands => commands.filter(command => command.name.includes('x')))
|
||||
powerbox.open();
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['b2x', 'b3x']);
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
it('should filter commands with `isDisabled`', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
let disableCommands = false;
|
||||
const powerbox = new Powerbox({
|
||||
categories: [],
|
||||
commands: [
|
||||
{category: 'a', name: 'a2', isDisabled: () => disableCommands},
|
||||
{category: 'a', name: 'a3', isDisabled: () => disableCommands},
|
||||
{category: 'a', name: 'a1', isDisabled: () => disableCommands},
|
||||
{category: 'b', name: 'b2x'},
|
||||
{category: 'b', name: 'b3x'},
|
||||
{category: 'b', name: 'b1y'},
|
||||
],
|
||||
editable,
|
||||
});
|
||||
powerbox.open();
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'a2', 'a3', 'b1y', 'b2x', 'b3x']);
|
||||
powerbox.close();
|
||||
disableCommands = true;
|
||||
powerbox.open();
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['b1y', 'b2x', 'b3x']);
|
||||
powerbox.close();
|
||||
disableCommands = false;
|
||||
powerbox.open();
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'a2', 'a3', 'b1y', 'b2x', 'b3x']);
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
it('should filter commands with filter text', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
editable.append(document.createTextNode('original text'));
|
||||
setSelection(editable.firstChild, 13);
|
||||
const powerbox = new Powerbox({
|
||||
categories: [],
|
||||
commands: [
|
||||
{category: 'a', name: 'a2'},
|
||||
{category: 'a', name: 'a3'},
|
||||
{category: 'a', name: 'a1'},
|
||||
{category: 'b', name: 'b2x'},
|
||||
{category: 'b', name: 'b3x'},
|
||||
{category: 'b', name: 'b1y'},
|
||||
],
|
||||
editable,
|
||||
});
|
||||
powerbox.open();
|
||||
window.chai.expect(powerbox._context.initialValue).to.eql('original text');
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'a2', 'a3', 'b1y', 'b2x', 'b3x']);
|
||||
// filter: '1'
|
||||
editable.append(document.createTextNode('1'));
|
||||
triggerEvent(editable, 'keyup');
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'b1y']);
|
||||
// filter: ''
|
||||
editable.lastChild.remove();
|
||||
triggerEvent(editable, 'keyup');
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'a2', 'a3', 'b1y', 'b2x', 'b3x']);
|
||||
// filter: 'a'
|
||||
editable.append(document.createTextNode('a'));
|
||||
triggerEvent(editable, 'keyup'); // filter: 'a'.
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'a2', 'a3']);
|
||||
editable.append(document.createTextNode('1'));
|
||||
triggerEvent(editable, 'keyup'); // filter: 'a1'.
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1']);
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
it('should close the Powerbox on remove last filter text with Backspace', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
editable.append(document.createTextNode('1'));
|
||||
setSelection(editable.firstChild, 13);
|
||||
const powerbox = new Powerbox({
|
||||
categories: [],
|
||||
commands: [
|
||||
{category: 'a', name: 'a2'},
|
||||
{category: 'a', name: 'a3'},
|
||||
{category: 'a', name: 'a1'},
|
||||
{category: 'b', name: 'b2x'},
|
||||
{category: 'b', name: 'b3x'},
|
||||
{category: 'b', name: 'b1y'},
|
||||
],
|
||||
editable,
|
||||
});
|
||||
powerbox.open();
|
||||
// Text: '1'
|
||||
window.chai.expect(powerbox._context.initialValue).to.eql('1');
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'a2', 'a3', 'b1y', 'b2x', 'b3x']);
|
||||
// Text: '1y' -> filter: 'y'
|
||||
editable.append(document.createTextNode('x'));
|
||||
triggerEvent(editable, 'keyup');
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['b2x', 'b3x']);
|
||||
// Text: '1'
|
||||
editable.lastChild.remove();
|
||||
triggerEvent(editable, 'keydown', { key: 'Backspace' });
|
||||
triggerEvent(editable, 'keyup');
|
||||
window.chai.expect(getCurrentCommandNames(powerbox)).to.eql(['a1', 'a2', 'a3', 'b1y', 'b2x', 'b3x']);
|
||||
window.chai.expect(powerbox.isOpen).to.eql(true);
|
||||
window.chai.expect(powerbox.el.style.display).not.to.eql('none');
|
||||
// Text: ''
|
||||
editable.lastChild.remove();
|
||||
triggerEvent(editable, 'keydown', { key: 'Backspace' });
|
||||
triggerEvent(editable, 'keyup');
|
||||
window.chai.expect(powerbox.isOpen).to.eql(false);
|
||||
window.chai.expect(powerbox.el.style.display).to.eql('none');
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
it('should close the Powerbox on press Escape', async () => {
|
||||
const editable = document.createElement('div');
|
||||
document.body.append(editable);
|
||||
const powerbox = new Powerbox({
|
||||
categories: [],
|
||||
commands: [
|
||||
{category: 'a', name: '2'},
|
||||
{category: 'a', name: '3'},
|
||||
{category: 'a', name: '1'},
|
||||
],
|
||||
editable,
|
||||
});
|
||||
powerbox.open();
|
||||
window.chai.expect(powerbox.isOpen).to.eql(true);
|
||||
window.chai.expect(powerbox.el.style.display).not.to.eql('none');
|
||||
triggerEvent(editable, 'keydown', { key: 'Escape' });
|
||||
window.chai.expect(powerbox.isOpen).to.eql(false);
|
||||
window.chai.expect(powerbox.el.style.display).to.eql('none');
|
||||
powerbox.destroy();
|
||||
editable.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user