2025-12-30 11:52:39 +00:00
|
|
|
import { tap, expect, webhelpers } from '@git.zone/tstest/tapbundle';
|
2025-06-24 22:45:50 +00:00
|
|
|
|
|
|
|
|
import * as deesCatalog from '../ts_web/index.js';
|
2025-12-19 12:36:12 +00:00
|
|
|
import { BlockRegistry } from '../ts_web/elements/00group-input/dees-input-wysiwyg/blocks/block.registry.js';
|
|
|
|
|
import { DeesWysiwygBlock } from '../ts_web/elements/00group-input/dees-input-wysiwyg/dees-wysiwyg-block.js';
|
2025-06-24 22:45:50 +00:00
|
|
|
|
|
|
|
|
// Import block registration to ensure handlers are registered
|
2025-12-19 12:36:12 +00:00
|
|
|
import '../ts_web/elements/00group-input/dees-input-wysiwyg/wysiwyg.blockregistration.js';
|
2025-06-24 22:45:50 +00:00
|
|
|
|
|
|
|
|
tap.test('BlockRegistry should have registered handlers', async () => {
|
|
|
|
|
// Test divider handler
|
|
|
|
|
const dividerHandler = BlockRegistry.getHandler('divider');
|
|
|
|
|
expect(dividerHandler).toBeDefined();
|
|
|
|
|
expect(dividerHandler?.type).toEqual('divider');
|
|
|
|
|
|
|
|
|
|
// Test paragraph handler
|
|
|
|
|
const paragraphHandler = BlockRegistry.getHandler('paragraph');
|
|
|
|
|
expect(paragraphHandler).toBeDefined();
|
|
|
|
|
expect(paragraphHandler?.type).toEqual('paragraph');
|
|
|
|
|
|
|
|
|
|
// Test heading handlers
|
|
|
|
|
const heading1Handler = BlockRegistry.getHandler('heading-1');
|
|
|
|
|
expect(heading1Handler).toBeDefined();
|
|
|
|
|
expect(heading1Handler?.type).toEqual('heading-1');
|
|
|
|
|
|
|
|
|
|
const heading2Handler = BlockRegistry.getHandler('heading-2');
|
|
|
|
|
expect(heading2Handler).toBeDefined();
|
|
|
|
|
expect(heading2Handler?.type).toEqual('heading-2');
|
|
|
|
|
|
|
|
|
|
const heading3Handler = BlockRegistry.getHandler('heading-3');
|
|
|
|
|
expect(heading3Handler).toBeDefined();
|
|
|
|
|
expect(heading3Handler?.type).toEqual('heading-3');
|
|
|
|
|
|
|
|
|
|
// Test that getAllTypes returns all registered types
|
|
|
|
|
const allTypes = BlockRegistry.getAllTypes();
|
|
|
|
|
expect(allTypes).toContain('divider');
|
|
|
|
|
expect(allTypes).toContain('paragraph');
|
|
|
|
|
expect(allTypes).toContain('heading-1');
|
|
|
|
|
expect(allTypes).toContain('heading-2');
|
|
|
|
|
expect(allTypes).toContain('heading-3');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should render divider block using handler', async () => {
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for custom element to be defined
|
|
|
|
|
await customElements.whenDefined('dees-wysiwyg-block');
|
|
|
|
|
|
|
|
|
|
// Create element and set properties BEFORE attaching to DOM
|
|
|
|
|
const dividerBlock = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Set required handlers
|
|
|
|
|
dividerBlock.handlers = {
|
|
|
|
|
onInput: () => {},
|
|
|
|
|
onKeyDown: () => {},
|
|
|
|
|
onFocus: () => {},
|
|
|
|
|
onBlur: () => {},
|
|
|
|
|
onCompositionStart: () => {},
|
|
|
|
|
onCompositionEnd: () => {}
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Set a divider block
|
|
|
|
|
dividerBlock.block = {
|
|
|
|
|
id: 'test-divider',
|
|
|
|
|
type: 'divider',
|
|
|
|
|
content: ' '
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
// Attach to DOM and wait for render
|
|
|
|
|
document.body.appendChild(dividerBlock);
|
2025-06-24 22:45:50 +00:00
|
|
|
await dividerBlock.updateComplete;
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for firstUpdated to populate the container
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Check that the divider is rendered
|
|
|
|
|
const dividerElement = dividerBlock.shadowRoot?.querySelector('.block.divider');
|
2025-12-30 12:24:16 +00:00
|
|
|
expect(dividerElement).toBeTruthy();
|
2025-06-24 22:45:50 +00:00
|
|
|
expect(dividerElement?.getAttribute('tabindex')).toEqual('0');
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
// Check for the hr element (divider uses <hr> not .divider-icon)
|
|
|
|
|
const hr = dividerBlock.shadowRoot?.querySelector('hr');
|
|
|
|
|
expect(hr).toBeTruthy();
|
|
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
|
document.body.removeChild(dividerBlock);
|
2025-06-24 22:45:50 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should render paragraph block using handler', async () => {
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for custom element to be defined
|
|
|
|
|
await customElements.whenDefined('dees-wysiwyg-block');
|
|
|
|
|
|
|
|
|
|
// Create element and set properties BEFORE attaching to DOM
|
|
|
|
|
const paragraphBlock = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Set required handlers
|
|
|
|
|
paragraphBlock.handlers = {
|
|
|
|
|
onInput: () => {},
|
|
|
|
|
onKeyDown: () => {},
|
|
|
|
|
onFocus: () => {},
|
|
|
|
|
onBlur: () => {},
|
|
|
|
|
onCompositionStart: () => {},
|
|
|
|
|
onCompositionEnd: () => {},
|
|
|
|
|
onMouseUp: () => {}
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Set a paragraph block
|
|
|
|
|
paragraphBlock.block = {
|
|
|
|
|
id: 'test-paragraph',
|
|
|
|
|
type: 'paragraph',
|
|
|
|
|
content: 'Test paragraph content'
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
// Attach to DOM and wait for render
|
|
|
|
|
document.body.appendChild(paragraphBlock);
|
2025-06-24 22:45:50 +00:00
|
|
|
await paragraphBlock.updateComplete;
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for firstUpdated to populate the container
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Check that the paragraph is rendered
|
|
|
|
|
const paragraphElement = paragraphBlock.shadowRoot?.querySelector('.block.paragraph');
|
2025-12-30 12:24:16 +00:00
|
|
|
expect(paragraphElement).toBeTruthy();
|
2025-06-24 22:45:50 +00:00
|
|
|
expect(paragraphElement?.getAttribute('contenteditable')).toEqual('true');
|
|
|
|
|
expect(paragraphElement?.textContent).toEqual('Test paragraph content');
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
|
document.body.removeChild(paragraphBlock);
|
2025-06-24 22:45:50 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('should render heading blocks using handler', async () => {
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for custom element to be defined
|
|
|
|
|
await customElements.whenDefined('dees-wysiwyg-block');
|
|
|
|
|
|
|
|
|
|
// Test heading-1 - set properties BEFORE attaching to DOM
|
|
|
|
|
const heading1Block = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
heading1Block.handlers = {
|
|
|
|
|
onInput: () => {},
|
|
|
|
|
onKeyDown: () => {},
|
|
|
|
|
onFocus: () => {},
|
|
|
|
|
onBlur: () => {},
|
|
|
|
|
onCompositionStart: () => {},
|
|
|
|
|
onCompositionEnd: () => {},
|
|
|
|
|
onMouseUp: () => {}
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
heading1Block.block = {
|
|
|
|
|
id: 'test-h1',
|
|
|
|
|
type: 'heading-1',
|
|
|
|
|
content: 'Heading 1 Test'
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
document.body.appendChild(heading1Block);
|
2025-06-24 22:45:50 +00:00
|
|
|
await heading1Block.updateComplete;
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for firstUpdated to populate the container
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
const h1Element = heading1Block.shadowRoot?.querySelector('.block.heading-1');
|
2025-12-30 12:24:16 +00:00
|
|
|
expect(h1Element).toBeTruthy();
|
2025-06-24 22:45:50 +00:00
|
|
|
expect(h1Element?.textContent).toEqual('Heading 1 Test');
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
// Clean up heading-1
|
|
|
|
|
document.body.removeChild(heading1Block);
|
|
|
|
|
|
|
|
|
|
// Test heading-2 - set properties BEFORE attaching to DOM
|
|
|
|
|
const heading2Block = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
heading2Block.handlers = {
|
|
|
|
|
onInput: () => {},
|
|
|
|
|
onKeyDown: () => {},
|
|
|
|
|
onFocus: () => {},
|
|
|
|
|
onBlur: () => {},
|
|
|
|
|
onCompositionStart: () => {},
|
|
|
|
|
onCompositionEnd: () => {},
|
|
|
|
|
onMouseUp: () => {}
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
heading2Block.block = {
|
|
|
|
|
id: 'test-h2',
|
|
|
|
|
type: 'heading-2',
|
|
|
|
|
content: 'Heading 2 Test'
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
document.body.appendChild(heading2Block);
|
2025-06-24 22:45:50 +00:00
|
|
|
await heading2Block.updateComplete;
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for firstUpdated to populate the container
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
const h2Element = heading2Block.shadowRoot?.querySelector('.block.heading-2');
|
2025-12-30 12:24:16 +00:00
|
|
|
expect(h2Element).toBeTruthy();
|
2025-06-24 22:45:50 +00:00
|
|
|
expect(h2Element?.textContent).toEqual('Heading 2 Test');
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
// Clean up heading-2
|
|
|
|
|
document.body.removeChild(heading2Block);
|
2025-06-24 22:45:50 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('paragraph block handler methods should work', async () => {
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for custom element to be defined
|
|
|
|
|
await customElements.whenDefined('dees-wysiwyg-block');
|
|
|
|
|
|
|
|
|
|
// Create element and set properties BEFORE attaching to DOM
|
|
|
|
|
const paragraphBlock = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Set required handlers
|
|
|
|
|
paragraphBlock.handlers = {
|
|
|
|
|
onInput: () => {},
|
|
|
|
|
onKeyDown: () => {},
|
|
|
|
|
onFocus: () => {},
|
|
|
|
|
onBlur: () => {},
|
|
|
|
|
onCompositionStart: () => {},
|
|
|
|
|
onCompositionEnd: () => {},
|
|
|
|
|
onMouseUp: () => {}
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
paragraphBlock.block = {
|
|
|
|
|
id: 'test-methods',
|
|
|
|
|
type: 'paragraph',
|
|
|
|
|
content: 'Initial content'
|
|
|
|
|
};
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
document.body.appendChild(paragraphBlock);
|
2025-06-24 22:45:50 +00:00
|
|
|
await paragraphBlock.updateComplete;
|
2025-12-30 12:24:16 +00:00
|
|
|
// Wait for firstUpdated to populate the container
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Test getContent
|
|
|
|
|
const content = paragraphBlock.getContent();
|
|
|
|
|
expect(content).toEqual('Initial content');
|
2025-12-30 12:24:16 +00:00
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Test setContent
|
|
|
|
|
paragraphBlock.setContent('Updated content');
|
|
|
|
|
await paragraphBlock.updateComplete;
|
|
|
|
|
expect(paragraphBlock.getContent()).toEqual('Updated content');
|
2025-12-30 12:24:16 +00:00
|
|
|
|
2025-06-24 22:45:50 +00:00
|
|
|
// Test that the DOM is updated
|
|
|
|
|
const paragraphElement = paragraphBlock.shadowRoot?.querySelector('.block.paragraph');
|
|
|
|
|
expect(paragraphElement?.textContent).toEqual('Updated content');
|
2025-12-30 12:24:16 +00:00
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
|
document.body.removeChild(paragraphBlock);
|
2025-06-24 22:45:50 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default tap.start();
|