mirror of
https://github.com/discourse/discourse.git
synced 2026-08-14 13:58:53 +08:00
258 lines
7.2 KiB
Ruby
Vendored
258 lines
7.2 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
describe "Composer - ProseMirror editor - Spoiler extension" do
|
|
fab!(:current_user) do
|
|
Fabricate(
|
|
:user,
|
|
refresh_auto_groups: true,
|
|
composition_mode: UserOption.composition_mode_types[:rich],
|
|
)
|
|
end
|
|
|
|
let(:cdp) { PageObjects::CDP.new }
|
|
let(:composer) { PageObjects::Components::Composer.new }
|
|
let(:rich) { composer.rich_editor }
|
|
|
|
def click_spoiler_button
|
|
find(".toolbar-menu__options-trigger").click
|
|
find("[title='#{I18n.t("js.spoiler.title")}']").click
|
|
end
|
|
|
|
before { sign_in(current_user) }
|
|
|
|
def open_composer
|
|
page.visit "/new-topic"
|
|
expect(composer).to be_opened
|
|
composer.focus
|
|
end
|
|
|
|
it "creates inline spoiler when cursor is at end of line" do
|
|
open_composer
|
|
|
|
composer.type_content("This is a test ")
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("span.spoiled", text: I18n.t("js.composer.spoiler_text"))
|
|
|
|
composer.type_content("spoiler")
|
|
|
|
expect(rich).to have_css("span.spoiled", text: "spoiler")
|
|
|
|
composer.toggle_rich_editor
|
|
|
|
expect(composer).to have_value("This is a test [spoiler]spoiler[/spoiler] ")
|
|
end
|
|
|
|
it "creates block spoiler when cursor is at start of line" do
|
|
open_composer
|
|
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("div.spoiled", text: I18n.t("js.composer.spoiler_text"))
|
|
|
|
composer.type_content("spoiler")
|
|
composer.toggle_rich_editor
|
|
|
|
expect(composer).to have_value("[spoiler]\nspoiler\n\n[/spoiler]\n\n")
|
|
end
|
|
|
|
it "creates block spoiler with input rule when cursor is at start of line" do
|
|
open_composer
|
|
composer.type_content("[spoiler]")
|
|
composer.type_content("inside")
|
|
composer.toggle_rich_editor
|
|
|
|
expect(composer).to have_value("[spoiler]\ninside\n\n[/spoiler]\n\n")
|
|
end
|
|
|
|
it "wraps selected text in inline spoiler when selection is within same paragraph" do
|
|
open_composer
|
|
|
|
composer.type_content("This is **secret** text here")
|
|
find("strong", text: "secret").double_click
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("span.spoiled strong", text: "secret")
|
|
expect(rich).to have_content("This is secret text here")
|
|
|
|
composer.toggle_rich_editor
|
|
expect(composer).to have_value("This is [spoiler]**secret**[/spoiler] text here")
|
|
end
|
|
|
|
it "wraps selected text in block spoiler when selection spans multiple paragraphs" do
|
|
open_composer
|
|
|
|
composer.type_content("First paragraph")
|
|
composer.send_keys(:enter)
|
|
composer.type_content("Second paragraph")
|
|
composer.select_all
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("div.spoiled p", text: "First paragraph")
|
|
expect(rich).to have_css("div.spoiled p", text: "Second paragraph")
|
|
|
|
composer.toggle_rich_editor
|
|
expect(composer).to have_value(
|
|
"[spoiler]\nFirst paragraph\n\nSecond paragraph\n\n[/spoiler]\n\n",
|
|
)
|
|
end
|
|
|
|
it "removes inline spoiler when cursor is inside inline spoiler" do
|
|
open_composer
|
|
|
|
composer.type_content("This is a test")
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("span.spoiled", text: I18n.t("js.composer.spoiler_text"))
|
|
|
|
composer.type_content("secret")
|
|
composer.send_keys(:left, :left, :left)
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_no_css("span.spoiled")
|
|
expect(rich).to have_content("This is a testsecret")
|
|
end
|
|
|
|
it "removes spoiler when cursor is inside block spoiler" do
|
|
open_composer
|
|
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("div.spoiled")
|
|
|
|
composer.type_content("secret content")
|
|
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_no_css("div.spoiled")
|
|
expect(rich).to have_css("p", text: "secret content")
|
|
end
|
|
|
|
it "removes spoiler when text is selected within spoiler" do
|
|
open_composer
|
|
|
|
composer.type_content("Normal text")
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("span.spoiled", text: I18n.t("js.composer.spoiler_text"))
|
|
|
|
composer.type_content("hidden text")
|
|
|
|
expect(rich).to have_css("span.spoiled", text: "hidden text")
|
|
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_no_css("span.spoiled")
|
|
expect(rich).to have_content("Normal texthidden text")
|
|
end
|
|
|
|
it "handles multi-blocks spoiler full lift" do
|
|
open_composer
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("div.spoiled")
|
|
|
|
composer.type_content("First paragraph\nSecond paragraph")
|
|
composer.send_keys(:up)
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_no_css("div.spoiled")
|
|
expect(rich).to have_css("p", text: "First paragraph")
|
|
expect(rich).to have_css("p", text: "Second paragraph")
|
|
|
|
composer.toggle_rich_editor
|
|
expect(composer).to have_value("First paragraph\n\nSecond paragraph")
|
|
end
|
|
|
|
it "breaks out of inline spoiler when pressing Enter" do
|
|
open_composer
|
|
|
|
composer.type_content("Test ")
|
|
|
|
expect(rich).to have_css("p", text: "Test")
|
|
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("span.spoiled", text: I18n.t("js.composer.spoiler_text"))
|
|
|
|
composer.type_content("hello")
|
|
composer.send_keys(:right)
|
|
composer.type_content("X")
|
|
|
|
expect(rich).to have_css("span.spoiled.spoiler-blurred", text: "hello")
|
|
|
|
composer.send_keys(:left, :left)
|
|
|
|
expect(rich).to have_css("span.spoiled:not(.spoiler-blurred)", text: "hello")
|
|
|
|
composer.send_keys(:enter)
|
|
expect(rich).to have_css("p:has(span.spoiled) + p", text: "X")
|
|
|
|
composer.send_keys(:backspace)
|
|
expect(rich).to have_no_css("p + p")
|
|
|
|
# Position cursor at "hell|o"
|
|
select_text_range(".ProseMirror span.spoiled", 4, 0)
|
|
|
|
expect(rich).to have_css("span.spoiled:not(.spoiler-blurred)", text: "hello")
|
|
|
|
composer.send_keys(:enter)
|
|
|
|
expect(rich).to have_css("p", text: "Test")
|
|
expect(rich).to have_css("span.spoiled", text: "hell")
|
|
expect(rich).to have_css("p:has(span.spoiled) + p", text: "o X")
|
|
end
|
|
|
|
it "keeps inline spoiler when pressing Enter at start of node" do
|
|
open_composer
|
|
|
|
composer.type_content(" ")
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("span.spoiled", text: I18n.t("js.composer.spoiler_text"))
|
|
|
|
composer.type_content("hello")
|
|
|
|
expect(rich).to have_css("span.spoiled", text: "hello")
|
|
|
|
# Position cursor at start of "hello" inside the spoiler — :control, :left has
|
|
# platform-dependent behavior (word-jump on Linux/Windows, line-jump on macOS).
|
|
select_text_range(".ProseMirror span.spoiled", 0, 0)
|
|
|
|
composer.send_keys(:backspace)
|
|
composer.send_keys(:enter)
|
|
|
|
expect(rich).to have_css("p:not(:has(span.spoiled)) + p:has(span.spoiled)", text: "hello")
|
|
end
|
|
|
|
it "selects the resulting node after a select all and spoiler click" do
|
|
open_composer
|
|
|
|
composer.type_content("This is a test")
|
|
composer.select_all
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("div.spoiled", text: "This is a test")
|
|
|
|
composer.type_content("spoiled")
|
|
|
|
composer.toggle_rich_editor
|
|
expect(composer).to have_value("[spoiler]\nspoiled\n\n[/spoiler]\n\n")
|
|
end
|
|
|
|
it "can spoiler a block node selection" do
|
|
open_composer
|
|
|
|
composer.type_content("> Blockquote")
|
|
|
|
find("blockquote").click(SystemHelpers::PLATFORM_KEY_MODIFIER)
|
|
find("blockquote").click(SystemHelpers::PLATFORM_KEY_MODIFIER)
|
|
|
|
click_spoiler_button
|
|
|
|
expect(rich).to have_css("div.spoiled", text: "Blockquote")
|
|
|
|
composer.toggle_rich_editor
|
|
expect(composer).to have_value("[spoiler]\n> Blockquote\n\n[/spoiler]\n\n")
|
|
end
|
|
end
|