Skip to content

Commit

Permalink
Add test for ckeditor4 integration
Browse files Browse the repository at this point in the history
  • Loading branch information
fsbraun committed Dec 12, 2024
1 parent c9651b2 commit 9284c02
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 15 deletions.
3 changes: 1 addition & 2 deletions djangocms_text/editors.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,7 @@ def get_editor_config(editor: Optional[str] = None) -> RTEConfig:
:rtype: RTEConfig
"""

TEXT_EDITOR = getattr(settings, "TEXT_EDITOR", "tiptap")
config = TEXT_EDITOR if editor is None else editor
config = editor or getattr(settings, "TEXT_EDITOR", "tiptap")
if "." in config and config not in configuration:
# Load the configuration from the module
module = __import__(config.rsplit(".", 1)[0], fromlist=[""])
Expand Down
72 changes: 60 additions & 12 deletions djangocms_text/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,67 @@ def get_url_endpoint():


class TextEditorWidget(forms.Textarea):
class Media:
css = {
**rte_config.css,
"all": (
"djangocms_text/css/cms.text.css",
"djangocms_text/css/cms.normalize.css",
*rte_config.css.get("all", ()),
"""
A widget for editing text content and plugins in a CMS environment.
This class extends the standard Django forms.Textarea widget, providing additional
capabilities to edit and manage content enriched with plugins. It integrates with
CMS systems and supports rendering, configuration, and customization of the text editor.
The widget is designed to adapt to a plugin-based architecture for seamless content creation
and management. It leverages specific editor settings, installed plugins, and placeholders,
while also supporting dynamic configurations tailored to individual plugin instances.
Attributes:
editor_class (str): The CSS class used to initialize the text editor.
editor_settings_id (str): Unique identifier for widget-specific editor settings.
global_settings_id (str): Shared identifier for global editor settings.
installed_plugins (list): A list of plugins available for text enhancement.
pk (str | int): The primary key of the associated plugin instance.
placeholder (str | int | None): The placeholder associated with the widget, if applicable.
plugin_language (str | None): The language used within the plugin.
plugin_position (int | None): Position of the plugin relative to others.
configuration (dict): Configuration settings for the text editor.
cancel_url (str | None): URL used to cancel editor actions.
url_endpoint (str | None): Endpoint for editor-related HTTP API calls.
render_plugin_url (str | None): URL for rendering plugin content.
messages_url (str | None): URL for fetching editor-related messages.
action_token (str | None): A token used to perform secured editor actions.
revert_on_cancel (bool): Whether changes are reverted upon cancellation.
body_css_classes (str): CSS classes for text editor's body element.
Args:
attrs: Optional dictionary of widget attributes.
installed_plugins: A list containing details of plugins enabled for the widget.
pk: The primary key identifying the plugin instance.
placeholder: A placeholder instance or its identifier for the widget's context.
plugin_language: A string specifying the language of the plugin in the editor context.
plugin_position: The integer position of the plugin among others.
configuration: Optional custom configuration dictionary for the widget editor.
cancel_url: A string representing the URL to redirect after cancellation.
url_endpoint: A string URL endpoint for backend interaction.
render_plugin_url: A string URL for rendering plugin output.
messages_url: A string URL for retrieving informational messages.
action_token: A secure action token string for backend interaction.
revert_on_cancel: A boolean flag to enable or disable reversion of changes on cancellation.
body_css_classes: A string for CSS classes to be attached to the editor body.
"""
@property
def media(self):
rte_config = get_editor_config()
return forms.Media(
css={
**rte_config.css,
"all": (
"djangocms_text/css/cms.text.css",
"djangocms_text/css/cms.normalize.css",
*rte_config.css.get("all", ()),
),
},
js=(
static_with_version("cms/js/dist/bundle.admin.base.min.js"),
"djangocms_text/bundles/bundle.editor.min.js",
*rte_config.js,
),
}
js = (
static_with_version("cms/js/dist/bundle.admin.base.min.js"),
"djangocms_text/bundles/bundle.editor.min.js",
*rte_config.js,
)

def __init__(
Expand Down
2 changes: 1 addition & 1 deletion private/js/ckeditor4_plugins/cmsplugins/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ import CmsDialog from "../../cms.dialog";
editor.fire('updateSnapshot');
})
.catch(error => {
console.warn(error);
console.error(error);
});
}
editor.focus();
Expand Down
39 changes: 39 additions & 0 deletions tests/integration/test_ckeditor4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pytest
from cms.utils.urlutils import admin_reverse
from playwright.sync_api import expect

from tests.fixtures import DJANGO_CMS4
from tests.integration.utils import login


@pytest.fixture
def use_ckeditor4(settings):
settings.TEXT_EDITOR = "djangocms_text.contrib.text_ckeditor4.ckeditor4"
yield
del settings.TEXT_EDITOR


@pytest.mark.django_db
@pytest.mark.skipif(not DJANGO_CMS4, reason="Integration tests only work on Django CMS 4")
def test_editor_loads(live_server, page, text_plugin, superuser, use_ckeditor4):
"""Test that tiptap editor loads and initializes properly"""
# Navigate to the text plugin add view
login(live_server, page, superuser)

console_errors = []

def handle_console_message(msg):
if msg.type == "error":
console_errors.append(msg.text)

page.on("console", handle_console_message)

page.goto(f"{live_server.url}{admin_reverse('cms_placeholder_edit_plugin', args=(text_plugin.pk,))}")

editor = page.locator(".cke.cke_reset")
expect(editor).to_be_visible() # Editor

expect(page.locator('.cke_top.cke_reset_all')).to_be_visible() # its menu bar
expect(page.locator('.cke_button.cke_button__bold')).to_be_visible() # a button in the menu bar

assert not console_errors, f"Console errors found: {console_errors}"
7 changes: 7 additions & 0 deletions tests/integration/test_text_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ def test_editor_loads(live_server, page, text_plugin, superuser):
# Navigate to the text plugin add view
login(live_server, page, superuser)

console_errors = []

def handle_console_message(msg):
if msg.type == "error":
console_errors.append(msg.text)

page.goto(f"{live_server.url}{admin_reverse('cms_placeholder_edit_plugin', args=(text_plugin.pk,))}")

editor = page.locator(".cms-editor-inline-wrapper.fixed")
Expand All @@ -25,3 +31,4 @@ def test_editor_loads(live_server, page, text_plugin, superuser):
expect(page.locator('button[title="Bold"]')).to_be_visible() # a button in the menu bar

assert tiptap.inner_text() == "Test content"
assert not console_errors, f"Console errors found: {console_errors}"
1 change: 1 addition & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def __getitem__(self, item):
"djangocms_picture",
"djangocms_link",
"djangocms_text",
"djangocms_text.contrib.text_ckeditor4",
"tests.test_app",
]

Expand Down

0 comments on commit 9284c02

Please sign in to comment.