diff --git a/.rubocop.yml b/.rubocop.yml index b25149f..e51b9ac 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -27,3 +27,7 @@ RSpec/ExampleLength: RSpec/MultipleExpectations: # default 1 Max: 4 + +RSpec/MultipleMemoizedHelpers: + # default 5 + Max: 10 diff --git a/spec/page_objects/shared/quill_editor.rb b/spec/page_objects/shared/quill_editor.rb index 54bfe72..a46b7c9 100644 --- a/spec/page_objects/shared/quill_editor.rb +++ b/spec/page_objects/shared/quill_editor.rb @@ -2,45 +2,34 @@ module Shared class QuillEditor < HtmlEditor - SELECTOR = '.ql-container' - TOOLBAR_SELECTOR = '.ql-toolbar' + attr_reader :editor_selector, :toolbar_selector - attr_reader :toolbar, :toolbar_selector - - def initialize(selector: SELECTOR, toolbar_selector: TOOLBAR_SELECTOR) - super(selector: selector) - @toolbar = find(toolbar_selector) - @toolbar_selector = toolbar_selector + def initialize(container) + @editor_selector = "#{container} .ql-container" + @toolbar_selector = "#{container} .ql-toolbar" + super(selector: editor_selector) end + def content = content_element['innerHTML'] + def content_element @content_element ||= find("#{selector} .ql-editor") end - def control_selector(control) - case control&.to_sym - when :bold then "#{toolbar_selector} button.ql-bold" - when :italic then "#{toolbar_selector} button.ql-italic" - when :underline then "#{toolbar_selector} button.ql-underline" - when :link then "#{toolbar_selector} button.ql-link" - else raise "Invalid control #{control}" - end - end - def toggle_bold - find(control_selector(:bold)).click + find("#{toolbar_selector} button.ql-bold").click end def toggle_italic - find(control_selector(:italic)).click + find("#{toolbar_selector} button.ql-italic").click end def toggle_underline - find(control_selector(:underline)).click + find("#{toolbar_selector} button.ql-underline").click end def toggle_link - find(control_selector(:link)).click + find("#{toolbar_selector} button.ql-link").click end end end diff --git a/spec/support/string_clean_multiline.rb b/spec/support/string_clean_multiline.rb new file mode 100644 index 0000000..16fc0db --- /dev/null +++ b/spec/support/string_clean_multiline.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module StringCleanMultiline + refine String do + def clean_multiline + # Get rid of newlines and indentation spaces + strip.gsub(/\s*\n\s*/, "") + end + end +end diff --git a/spec/system/quill_editor_spec.rb b/spec/system/quill_editor_spec.rb index e853eb9..f0c5a73 100644 --- a/spec/system/quill_editor_spec.rb +++ b/spec/system/quill_editor_spec.rb @@ -1,114 +1,118 @@ # frozen_string_literal: true +using StringCleanMultiline + RSpec.describe 'Quill editor' do - def lookup_editor(field:) - selector = ["##{field}_input.quill_editor", Shared::QuillEditor::SELECTOR].join(' ') - toolbar_selector = ["##{field}_input.quill_editor", Shared::QuillEditor::TOOLBAR_SELECTOR].join(' ') - Shared::QuillEditor.new(selector: selector, toolbar_selector: toolbar_selector) + let(:author) { Author.create!(email: 'some_email@example.com', name: 'John Doe', age: 30) } + let(:post) do + Post.create!(title: 'Test', author: author, description: '
Some content
', summary: 'Post summary
') end - let(:author) { Author.create!(email: 'some_email@example.com', name: 'John Doe', age: 30) } - let!(:post) { Post.create!(title: 'Test', author: author, description: '') } + let(:submit_button) { find('#post_submit_action [type="submit"]') } context 'with a Quill editor' do - let(:editor) { lookup_editor(field: 'post_description') } - - before do + let(:edit_page) do path = edit_admin_post_path(post) - Admin::Posts::EditPage.new(path: path).load + Admin::Posts::EditPage.new(path: path) end + let(:editor) { edit_page.lookup_editor(editor_container: '#post_description_input') } + let(:input_field) { find('#post_description[data-aa-quill-editor]') } - it 'adds some text to the description', :aggregate_failures do - expect(page).to have_css('#post_description[data-aa-quill-editor]') - editor << 'Some content...' - %i[bold italic underline link].each do |control| - expect(page).to have_css editor.control_selector(control) - end - expect(editor.content_element).to have_content('Some content...') - expect { find('[type="submit"]').click } - .to change { post.reload.description }.to 'Some content...
' + before do + edit_page.load end - it 'adds some bold text to the description', :aggregate_failures do - editor.toolbar_control(:bold) - editor << 'Some bold text' - - expect(editor.content_element).to have_content('Some bold text') - expect { find('[type="submit"]').click } - .to change { post.reload.description }.to 'Some bold text
' + it 'initializes the editor', :aggregate_failures do + expect(editor.content_element).to be_present + expect(editor.content).to eq('Some content
') + expect(input_field).to be_present end - it 'adds some italic text to the description', :aggregate_failures do - editor.toolbar_control(:italic) - editor << 'Some italic text' - - expect(editor.content_element).to have_content('Some italic text') - expect { find('[type="submit"]').click } - .to change { post.reload.description }.to 'Some italic text
' + it 'edits some content using the editor' do + editor << :return << 'More content' + editor.toggle_bold + editor << 'Some bold' + editor.toggle_italic + editor << 'Some italic' + editor.toggle_underline + editor << 'Some underline' + + expect(editor.content).to eq <<~HTML.clean_multiline +Some content
+More contentSome boldSome italicSome underline
+ HTML end - it 'adds some underline text to the description', :aggregate_failures do - editor.toolbar_control(:underline) - editor << 'Some underline text' + it 'updates the field when submitting', :aggregate_failures do + editor.toggle_bold + editor << 'More content' - expect(editor.content_element).to have_content('Some underline text') - expect { find('[type="submit"]').click } - .to change { post.reload.description }.to 'Some underline text
' - end + before = 'Some content
' + after = 'More contentSome content
' + expect { submit_button.click }.to change { post.reload.description }.from(before).to(after) - it 'adds a link to the description', :aggregate_failures do - editor << "Just a link" - editor.select_all - editor.toolbar_control(:link) - editor.element.find('[data-link]').send_keys("https://www.google.com", :return) - - expect(editor.content_element).to have_content('Just a link') - html = '' - expect { find('[type="submit"]').click }.to change { post.reload.description }.to html + expect(page).to have_content('was successfully updated') end end context 'with 2 Quill editors' do - before do + let(:edit_page) do path = edit_admin_post_path(post) - Admin::Posts::EditPage.new(path: path).load + Admin::Posts::EditPage.new(path: path) + end + let(:first_editor) { edit_page.lookup_editor(editor_container: '#post_description_input') } + let(:second_editor) { edit_page.lookup_editor(editor_container: '#post_summary_input') } + + before do + edit_page.load end it 'updates some HTML content for 2 fields', :aggregate_failures do - editor1 = lookup_editor(field: 'post_description') - editor1.clear.toolbar_control(:bold) - editor1 << "Some description" + # Check the initial states + expect(first_editor.content).to eq('Some content
') + expect(second_editor.content).to eq('Post summary
') + + # Add some content to both the editors + first_editor.toggle_bold + first_editor << 'Some bold' - editor2 = lookup_editor(field: 'post_summary') - editor2.clear.toolbar_control(:italic) - editor2 << "Some summary" + second_editor.toggle_italic + second_editor << 'Some italic' - find('[type="submit"]').click - post.reload + # Check that both the fields change + before = 'Some content
' + after = 'Some boldSome content
' + expect { submit_button.click }.to change { post.reload.description }.from(before).to(after) - expect(post.description).to eq 'Some description
' - expect(post.summary).to eq 'Some summary
' + expect(post.summary).to eq 'Some italicPost summary
' end end context 'with a Quill editor in a nested resource' do - before do + let(:edit_page) do path = edit_admin_author_path(author) - Admin::Authors::EditPage.new(path: path).load + Admin::Authors::EditPage.new(path: path) + end + let(:submit_button) { find('#author_submit_action [type="submit"]') } + + before do + post + edit_page.load end it 'updates some HTML content of a new nested resource', :aggregate_failures do - find('.posts.has_many_container .has_many_add').click - expect(page).to have_css('.posts.has_many_container .ql-editor', count: 2) + click_on 'Add New Post' - editor = lookup_editor(field: 'author_posts_attributes_1_description') - editor << "Some post text" + first_editor = edit_page.lookup_editor(editor_container: '#author_posts_attributes_0_description_input') + expect(first_editor.content).to eq('Some content
') - fill_in('author[posts_attributes][1][title]', with: 'A new post') - find('[type="submit"]').click + fill_in('author[posts_attributes][1][title]', with: 'Some title') + second_editor = edit_page.lookup_editor(editor_container: '#author_posts_attributes_1_description_input') + second_editor.toggle_underline + second_editor << 'Some underline' - expect(page).to have_content('was successfully updated') - expect(author.posts.last.description).to eq 'Some post text
' + expect { submit_button.click }.to change(Post, :count).by(1) + expect(Post.last.description).to eq 'Some underline
' end end end