FIX: Fast edit doesn’t work on content with certain characters (#20410)

Small js fix for fast edit to allow posts to save changes when the post contains apostrophes and quotation marks. Replaces unicode characters in text prior to saving the edit.

Includes system tests for fast edit and introduces a new system spec component for fast edit usage.
This commit is contained in:
David Battersby 2023-02-23 11:30:16 +08:00 committed by GitHub
parent 576745637e
commit 0a619d8c88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 114 additions and 3 deletions

View File

@ -39,9 +39,9 @@ function getQuoteTitle(element) {
}
function fixQuotes(str) {
// u+201c
// u+201d ”
return str.replace(/[\u201C\u201D]/g, '"');
// u+201c, u+201d =
// u+2018, u+2019 =
return str.replace(/[\u201C\u201D]/g, '"').replace(/[\u2018\u2019]/g, "'");
}
export default Component.extend(KeyEnterEscape, {

View File

@ -80,4 +80,19 @@ module SystemHelpers
def using_session(name, &block)
Capybara.using_session(name.to_s + self.method_name, &block)
end
def select_text_range(selector, start = 0, offset = 5)
js = <<-JS
const node = document.querySelector(arguments[0]).childNodes[0];
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(node);
range.setStart(node, arguments[1]);
range.setEnd(node, arguments[1] + arguments[2]);
selection.removeAllRanges();
selection.addRange(range);
JS
page.execute_script(js, selector, start, offset)
end
end

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
describe "Fast edit", type: :system, js: true do
let(:topic_page) { PageObjects::Pages::Topic.new }
let(:fast_editor) { PageObjects::Components::FastEditor.new }
fab!(:topic) { Fabricate(:topic) }
fab!(:post) { Fabricate(:post, topic: topic) }
fab!(:post_2) { Fabricate(:post, topic: topic, raw: "It twas a great “time”!") }
fab!(:current_user) { Fabricate(:admin) }
before { sign_in(current_user) }
context "when text selected it opens contact menu and fast editor" do
it "opens context menu and fast edit dialog" do
topic_page.visit_topic(topic)
select_text_range("#{topic_page.post_by_number_selector(1)} .cooked p", 0, 10)
expect(topic_page.fast_edit_button).to be_visible
topic_page.click_fast_edit_button
expect(topic_page.fast_edit_input).to be_visible
end
it "edits first paragraph and saves changes" do
topic_page.visit_topic(topic)
select_text_range("#{topic_page.post_by_number_selector(1)} .cooked p", 0, 5)
topic_page.click_fast_edit_button
fast_editor.fill_content("Howdy")
fast_editor.save
within("#post_1 .cooked > p") do |el|
expect(el).not_to eq("Hello world")
expect(el).to have_content("Howdy")
end
end
end
context "when editing text that has strange characters" do
it "saves when paragraph contains apostrophe" do
topic_page.visit_topic(topic)
select_text_range("#{topic_page.post_by_number_selector(2)} .cooked p", 19, 4)
topic_page.click_fast_edit_button
fast_editor.fill_content("day")
fast_editor.save
expect(find("#{topic_page.post_by_number_selector(2)} .cooked p")).to have_content(
"It twas a great “day”!",
)
end
end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
module PageObjects
module Components
class FastEditor < PageObjects::Components::Base
def fill_content(content)
fast_edit_input.fill_in(with: content)
self
end
def clear_content
fill_content("")
end
def has_content?(content)
fast_edit_input.value == content
end
def save
find(".save-fast-edit").click
end
def fast_edit_input
find("#fast-edit-input")
end
end
end
end

View File

@ -5,6 +5,7 @@ module PageObjects
class Topic < PageObjects::Pages::Base
def initialize
@composer_component = PageObjects::Components::Composer.new
@fast_edit_component = PageObjects::Components::FastEditor.new
end
def visit_topic(topic)
@ -114,6 +115,18 @@ module PageObjects
@composer_component.fill_title(title)
end
def fast_edit_button
find(".quote-button .quote-edit-label")
end
def click_fast_edit_button
find(".quote-button .quote-edit-label").click
end
def fast_edit_input
@fast_edit_component.fast_edit_input
end
private
def topic_footer_button_id(button)