UNPKG

grapesjs_codeapps

Version:

Free and Open Source Web Builder Framework/SC Modification

545 lines (495 loc) 17.5 kB
const PluginManager = require('plugin_manager'); describe('GrapesJS', () => { describe('Main', () => { var obj; var fixtures; var fixture; var editorName; var htmlString; var config; var cssString; var documentEl; var storage; var storageId = 'testStorage'; var storageMock = { store(data, clb) { storage = data; clb(); }, load(keys, clb) { return clb(storage); } }; beforeAll(() => { editorName = 'editor-fixture'; }); beforeEach(() => { storage = {}; htmlString = '<div class="test1"></div><div class="test2"></div>'; cssString = '.test2{color:red}.test3{color:blue}'; documentEl = '<style>' + cssString + '</style>' + htmlString; config = { container: '#' + editorName, storageManager: { autoload: 0, autosave: 0, type: 0 } }; obj = grapesjs; document.body.innerHTML = `<div id="fixtures"><div id="${editorName}"></div></div>`; fixtures = document.body.querySelector('#fixtures'); fixture = document.body.querySelector(`#${editorName}`); }); afterEach(() => { var plugins = obj.plugins.getAll(); for (let id in plugins) { if (plugins.hasOwnProperty(id)) { delete plugins[id]; } } }); test('Main object should be loaded', () => { expect(obj).toBeTruthy(); }); test('Init new editor', () => { var editor = obj.init(config); expect(editor).toBeTruthy(); }); test('Init new editor with node for container', () => { var configAlt = { container: document.createElement('div'), storageManager: { autoload: 0, type: 'none' } }; var editor = obj.init(configAlt); expect(editor).toBeTruthy(); }); test('New editor is empty', () => { var editor = obj.init(config); var html = editor.getHtml(); //var css = editor.getCss(); var protCss = editor.getConfig().protectedCss; expect(html ? html : '').toBeFalsy(); //expect((css ? css : '')).toEqual(protCss); expect(editor.getComponents().length).toEqual(0); expect(editor.getStyle().length).toEqual(0); }); test('Editor canvas baseCSS can be overwritten', () => { config.components = htmlString; config.baseCss = '#wrapper { background-color: #eee; }'; config.protectedCss = ''; var editor = obj.init(config); expect(window.frames[0].document.documentElement.outerHTML).toContain( config.baseCss ); expect( window.frames[0].document.documentElement.outerHTML.replace(/\s+/g, ` `) ).not.toContain(`body { margin: 0;`); }); test('Editor canvas baseCSS defaults to sensible values if not defined', () => { config.components = htmlString; config.protectedCss = ''; var editor = obj.init(config); expect( window.frames[0].document.documentElement.outerHTML.replace(/\s+/g, ` `) ).toContain(`body { margin: 0;`); }); test('Init editor with html', () => { config.components = htmlString; var editor = obj.init(config); var comps = editor.DomComponents.getComponents(); expect(comps.length).toEqual(2); expect( comps .at(0) .get('classes') .at(0) .get('name') ).toEqual('test1'); }); test('Init editor with css', () => { config.style = cssString; var editor = obj.init(config); var rules = editor.CssComposer.getAll(); expect(rules.length).toEqual(2); expect( rules .at(0) .get('selectors') .at(0) .get('name') ).toEqual('test2'); }); test('Init editor from element', () => { config.fromElement = 1; config.storageManager = { type: 0 }; fixture.innerHTML = documentEl; const editor = obj.init(config); const html = editor.getHtml(); const css = editor.getCss(); const protCss = editor.getConfig().protectedCss; expect(html).toEqual(htmlString); expect(editor.getComponents().length).toEqual(2); // .test3 is discarded in CSS expect(css).toEqual(`${protCss}.test2{color:red;}`); // but it's still there expect(editor.getStyle().length).toEqual(2); }); test('Init editor from element with multiple font-face at-rules', () => { config.fromElement = 1; config.storageManager = { type: 0 }; fixture.innerHTML = ` <style> @font-face { font-family: 'A'; src: url('http://a.link') format('woff2'); } @font-face { font-family: 'B'; src: url('http://b.link') format('woff2'); } </style>` + htmlString; const editor = obj.init(config); const css = editor.getCss(); const styles = editor.getStyle(); expect(styles.length).toEqual(2); expect((css.match(/@font-face/g) || []).length).toEqual(2); }); test('Set components as HTML', () => { var editor = obj.init(config); editor.setComponents(htmlString); expect(editor.getComponents().length).toEqual(2); }); test('Set components as array of objects', () => { var editor = obj.init(config); editor.setComponents([{}, {}, {}]); expect(editor.getComponents().length).toEqual(3); }); test('Set style as CSS', () => { var editor = obj.init(config); editor.setStyle(cssString); editor.setStyle(cssString); var styles = editor.getStyle(); expect(styles.length).toEqual(2); expect( styles .at(1) .get('selectors') .at(0) .get('name') ).toEqual('test3'); }); test('Set style as as array of objects', () => { var editor = obj.init(config); editor.setStyle([{ selectors: ['test4'] }, { selectors: ['test5'] }]); var styles = editor.getStyle(); expect(styles.length).toEqual(2); expect( styles .at(1) .get('selectors') .at(0) .get('name') ).toEqual('test5'); }); test.skip('Adds new storage as plugin and store data there', done => { const pluginName = storageId + '-p2'; obj.plugins.add(pluginName, e => e.StorageManager.add(storageId, storageMock) ); config.storageManager.type = storageId; config.plugins = [pluginName]; const editor = obj.init(config); editor.setComponents(htmlString); editor.store(() => { editor.load(data => { expect(data.html).toEqual(htmlString); done(); }); }); }); test('Adds a new storage and fetch correctly data from it', done => { fixture.innerHTML = documentEl; const styleResult = { color: 'white', display: 'block' }; const style = [ { selectors: [{ name: 'sclass1' }], style: { color: 'green' } }, { selectors: [{ name: 'test2' }], style: styleResult }, { selectors: [{ name: 'test3' }], style: { color: 'black', display: 'block' } } ]; storage = { css: '* { box-sizing: border-box; } body {margin: 0;}', styles: JSON.stringify(style) }; const pluginName = storageId + '-p'; obj.plugins.add(pluginName, e => e.StorageManager.add(storageId, storageMock) ); config.fromElement = 1; config.storageManager.type = storageId; config.plugins = [pluginName]; config.storageManager.autoload = 1; const editor = obj.init(config); editor.on('load', () => { const cc = editor.CssComposer; expect(cc.getAll().length).toEqual(style.length); // expect(cc.setClassRule('test2').getStyle()).toEqual(styleResult); done(); }); }); test('Execute plugins with custom options', () => { var pluginName = storageId + '-plugin-opts'; obj.plugins.add(pluginName, (edt, opts) => { var opts = opts || {}; edt.customValue = opts.cVal || ''; }); config.plugins = [pluginName]; config.pluginsOpts = {}; config.pluginsOpts[pluginName] = { cVal: 'TEST' }; var editor = obj.init(config); expect(editor.customValue).toEqual('TEST'); }); test('Execute inline plugins with custom options', () => { const inlinePlugin = (edt, opts) => { var opts = opts || {}; edt.customValue = opts.cVal || ''; }; config.plugins = [inlinePlugin]; config.pluginsOpts = {}; config.pluginsOpts[inlinePlugin] = { cVal: 'TEST' }; var editor = obj.init(config); expect(editor.customValue).toEqual('TEST'); }); test('Execute inline plugins without any options', () => { const inlinePlugin = edt => { edt.customValue = 'TEST'; }; config.plugins = [inlinePlugin]; config.pluginsOpts = {}; var editor = obj.init(config); expect(editor.customValue).toEqual('TEST'); }); test('Use plugins defined on window, with custom options', () => { window.globalPlugin = (edt, opts) => { var opts = opts || {}; edt.customValue = opts.cVal || ''; }; config.plugins = ['globalPlugin']; config.pluginsOpts = {}; config.pluginsOpts['globalPlugin'] = { cVal: 'TEST' }; var editor = obj.init(config); expect(editor.customValue).toEqual('TEST'); }); test('Execute custom command', () => { var editor = obj.init(config); editor.testVal = ''; editor.setComponents(htmlString); editor.Commands.add('test-command', { run(ed, caller, opts) { ed.testVal = ed.getHtml() + opts.val; } }); editor.runCommand('test-command', { val: 5 }); expect(editor.testVal).toEqual(htmlString + '5'); }); test('Stop custom command', () => { var editor = obj.init(config); editor.testVal = ''; editor.setComponents(htmlString); editor.Commands.add('test-command', { stop(ed, caller, opts) { ed.testVal = ed.getHtml() + opts.val; } }); editor.stopCommand('test-command', { val: 5 }); expect(editor.testVal).toEqual(htmlString + '5'); }); test('Trigger custom command events', () => { const id = 'test-command'; const editor = obj.init(config); const result = {}; editor.on(`run:${id}`, () => (result.run = 1)); editor.on(`run:${id}:before`, () => (result.runBefore = 1)); editor.on(`stop:${id}`, () => (result.stop = 1)); editor.on(`stop:${id}:before`, () => (result.stopBefore = 1)); editor.on(`abort:${id}`, () => (result.abort = 1)); editor.Commands.add(id, { run() {}, stop() {} }); editor.runCommand(id); editor.stopCommand(id); editor.on(`run:${id}:before`, opts => (opts.abort = 1)); editor.runCommand(id); expect(result).toEqual({ run: 1, runBefore: 1, stop: 1, stopBefore: 1, abort: 1 }); }); test('Set default devices', () => { config.deviceManager = {}; config.deviceManager.devices = [ { name: '1', width: '2' }, { name: '3', width: '4' } ]; var editor = obj.init(config); expect(editor.DeviceManager.getAll().length).toEqual(2); }); test('There is no active device', () => { var editor = obj.init(config); expect(editor.getDevice()).toBeFalsy(); }); test('Active another device', () => { var editor = obj.init(config); editor.setDevice('Tablet'); expect(editor.getDevice()).toEqual('Tablet'); }); // Problems with iframe loading test('Init new editor with custom plugin overrides default commands', () => { var editor, pluginName = 'test-plugin-opts'; obj.plugins.add(pluginName, (edt, opts) => { let cmdm = edt.Commands; // Overwrite export template cmdm.add('export-template', { test: 1 }); }); config.plugins = [pluginName]; editor = obj.init(config); expect(editor.Commands.get('export-template').test).toEqual(1); }); test('Keep unused css classes/selectors option for getCSS method', () => { config.fromElement = 1; config.storageManager = { type: 0 }; fixture.innerHTML = documentEl; const editor = obj.init(config); const css = editor.getCss({ keepUnusedStyles: 1 }); const protCss = editor.getConfig().protectedCss; expect(editor.getStyle().length).toEqual(2); expect(css).toEqual(`${protCss}.test2{color:red;}.test3{color:blue;}`); }); test('Keep unused css classes/selectors option for media rules', () => { cssString = '.test2{color:red}.test3{color:blue} @media only screen and (max-width: 620px) { .notused { color: red; } } '; documentEl = '<style>' + cssString + '</style>' + htmlString; config.fromElement = 1; config.storageManager = { type: 0 }; fixture.innerHTML = documentEl; const editor = obj.init(config); const css = editor.getCss({ keepUnusedStyles: 1 }); const protCss = editor.getConfig().protectedCss; expect(editor.getStyle().length).toEqual(3); expect(css).toEqual( `${protCss}.test2{color:red;}.test3{color:blue;}@media only screen and (max-width: 620px){.notused{color:red;}}` ); }); test('Keep unused css classes/selectors option for init method', () => { config.fromElement = 1; config.storageManager = { type: 0 }; fixture.innerHTML = documentEl; const editor = obj.init({ ...config, keepUnusedStyles: 1 }); const css = editor.getCss(); const protCss = editor.getConfig().protectedCss; expect(editor.getStyle().length).toEqual(2); expect(css).toEqual(`${protCss}.test2{color:red;}.test3{color:blue;}`); }); describe('Component selection', () => { let editor, wrapper, el1, el2, el3; beforeEach(() => { config.storageManager = { type: 0 }; config.components = `<div> <div id="el1"></div> <div id="el2"></div> <div id="el3"></div> </div>`; editor = obj.init(config); wrapper = editor.DomComponents.getWrapper(); el1 = wrapper.find('#el1')[0]; el2 = wrapper.find('#el2')[0]; el3 = wrapper.find('#el3')[0]; }); test('Select a single component', () => { expect(editor.getSelected()).toBeFalsy(); expect(editor.getSelectedAll().length).toBe(0); // Select via component editor.select(el1); expect(editor.getSelected()).toBe(el1); expect(editor.getSelectedAll().length).toBe(1); // Select via element editor.select(el2.getEl()); expect(editor.getSelected()).toBe(el2); expect(editor.getSelectedAll().length).toBe(1); // Deselect via empty array editor.select([]); expect(editor.getSelected()).toBeFalsy(); expect(editor.getSelectedAll().length).toBe(0); }); test('Select multiple components', () => { // Select at first el1 and el3 editor.select([el1, el3.getEl()]); expect(editor.getSelected()).toBe(el3); expect(editor.getSelectedAll().length).toBe(2); // Add el2 editor.selectAdd(el2); expect(editor.getSelected()).toBe(el2); expect(editor.getSelectedAll().length).toBe(3); // Remove el1 editor.selectRemove(el1); expect(editor.getSelected()).toBe(el2); expect(editor.getSelectedAll().length).toBe(2); // Add el1 via toggle editor.selectToggle(el1); expect(editor.getSelected()).toBe(el1); expect(editor.getSelectedAll().length).toBe(3); // Leave selected only el3 editor.selectRemove([el1, el2]); expect(editor.getSelected()).toBe(el3); expect(editor.getSelectedAll().length).toBe(1); // Toggle all editor.selectToggle([el1, el2, el3]); expect(editor.getSelected()).toBe(el2); expect(editor.getSelectedAll().length).toBe(2); // Add mutiple editor.selectAdd([el2, el3]); expect(editor.getSelected()).toBe(el3); expect(editor.getSelectedAll().length).toBe(3); }); test('Selection events', () => { const toSpy = { selected() {}, deselected() {}, toggled() {} }; const selected = jest.spyOn(toSpy, 'selected'); const deselected = jest.spyOn(toSpy, 'deselected'); const toggled = jest.spyOn(toSpy, 'toggled'); editor.on('component:selected', selected); editor.on('component:deselected', deselected); editor.on('component:toggled', toggled); editor.select(el1); // selected=1 editor.selectAdd(el1); // selected=1 editor.selectAdd([el2, el3]); // selected=3 editor.selectToggle([el1, el3]); // deselected=2 editor.selectRemove(el2); // deselected=3 editor.select(el1); // selected=4 expect(selected).toBeCalledTimes(4); expect(deselected).toBeCalledTimes(3); expect(toggled).toBeCalledTimes(7); }); }); }); });