зеркало из
https://github.com/rs-pro/activeadmin-quill_editor.git
synced 2026-09-04 10:45:51 +03:00
Merge pull request #52 from blocknotes/test/improve-specs
test: Improve specs using page objects
Этот коммит содержится в:
@@ -2,11 +2,15 @@
|
|||||||
inherit_from:
|
inherit_from:
|
||||||
- https://relaxed.ruby.style/rubocop.yml
|
- https://relaxed.ruby.style/rubocop.yml
|
||||||
|
|
||||||
require:
|
plugins:
|
||||||
- rubocop-packaging
|
- rubocop-capybara
|
||||||
- rubocop-performance
|
- rubocop-performance
|
||||||
- rubocop-rails
|
- rubocop-rails
|
||||||
- rubocop-rspec
|
- rubocop-rspec
|
||||||
|
- rubocop-rspec_rails
|
||||||
|
|
||||||
|
require:
|
||||||
|
- rubocop-packaging
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
|||||||
2
Gemfile
2
Gemfile
@@ -38,10 +38,12 @@ gem 'rspec-retry'
|
|||||||
# Linters
|
# Linters
|
||||||
gem 'fasterer'
|
gem 'fasterer'
|
||||||
gem 'rubocop'
|
gem 'rubocop'
|
||||||
|
gem 'rubocop-capybara'
|
||||||
gem 'rubocop-packaging'
|
gem 'rubocop-packaging'
|
||||||
gem 'rubocop-performance'
|
gem 'rubocop-performance'
|
||||||
gem 'rubocop-rails'
|
gem 'rubocop-rails'
|
||||||
gem 'rubocop-rspec'
|
gem 'rubocop-rspec'
|
||||||
|
gem 'rubocop-rspec_rails'
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
gem 'pry-rails'
|
gem 'pry-rails'
|
||||||
|
|||||||
11
spec/page_objects/admin/authors/edit_page.rb
Обычный файл
11
spec/page_objects/admin/authors/edit_page.rb
Обычный файл
@@ -0,0 +1,11 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative '../../base_page'
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module Authors
|
||||||
|
class EditPage < BasePage
|
||||||
|
include Capybara::DSL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
spec/page_objects/admin/posts/edit_page.rb
Обычный файл
11
spec/page_objects/admin/posts/edit_page.rb
Обычный файл
@@ -0,0 +1,11 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative '../../base_page'
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module Posts
|
||||||
|
class EditPage < BasePage
|
||||||
|
include Capybara::DSL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
12
spec/page_objects/base_object.rb
Обычный файл
12
spec/page_objects/base_object.rb
Обычный файл
@@ -0,0 +1,12 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class BaseObject
|
||||||
|
include Capybara::DSL
|
||||||
|
|
||||||
|
attr_reader :element, :selector
|
||||||
|
|
||||||
|
def initialize(selector:)
|
||||||
|
@selector = selector
|
||||||
|
@element = find(selector)
|
||||||
|
end
|
||||||
|
end
|
||||||
15
spec/page_objects/base_page.rb
Обычный файл
15
spec/page_objects/base_page.rb
Обычный файл
@@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class BasePage
|
||||||
|
include Capybara::DSL
|
||||||
|
|
||||||
|
attr_reader :path
|
||||||
|
|
||||||
|
def initialize(path:)
|
||||||
|
@path = path
|
||||||
|
end
|
||||||
|
|
||||||
|
def load
|
||||||
|
visit(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
35
spec/page_objects/shared/html_editor.rb
Обычный файл
35
spec/page_objects/shared/html_editor.rb
Обычный файл
@@ -0,0 +1,35 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative '../base_object'
|
||||||
|
|
||||||
|
class HtmlEditor < BaseObject
|
||||||
|
def content_element
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear
|
||||||
|
select_all
|
||||||
|
content_element.send_keys(:delete)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [self]
|
||||||
|
def open_dropdown
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_all
|
||||||
|
content_element.send_keys([:control, "a"])
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def toolbar_control(control, ...)
|
||||||
|
send(:"toggle_#{control}", ...)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def <<(content)
|
||||||
|
content_element.send_keys(content)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
||||||
44
spec/page_objects/shared/quill_editor.rb
Обычный файл
44
spec/page_objects/shared/quill_editor.rb
Обычный файл
@@ -0,0 +1,44 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class QuillEditor < HtmlEditor
|
||||||
|
SELECTOR = '.ql-container'
|
||||||
|
TOOLBAR_SELECTOR = '.ql-toolbar'
|
||||||
|
|
||||||
|
attr_reader :toolbar, :toolbar_selector
|
||||||
|
|
||||||
|
def initialize(selector: SELECTOR, toolbar_selector: TOOLBAR_SELECTOR)
|
||||||
|
super(selector: selector)
|
||||||
|
@toolbar = find(toolbar_selector)
|
||||||
|
@toolbar_selector = toolbar_selector
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
def toggle_italic
|
||||||
|
find(control_selector(:italic)).click
|
||||||
|
end
|
||||||
|
|
||||||
|
def toggle_underline
|
||||||
|
find(control_selector(:underline)).click
|
||||||
|
end
|
||||||
|
|
||||||
|
def toggle_link
|
||||||
|
find(control_selector(:link)).click
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -12,7 +12,8 @@ require 'rspec/rails'
|
|||||||
require 'capybara/rails'
|
require 'capybara/rails'
|
||||||
require 'rspec/retry'
|
require 'rspec/retry'
|
||||||
|
|
||||||
Dir[File.expand_path('support/**/*.rb', __dir__)].each { |f| require_relative f }
|
Rails.root.glob("../support/**/*.rb").each { |f| require_relative f }
|
||||||
|
Rails.root.glob("../page_objects/**/*.rb").each { |f| require_relative f }
|
||||||
|
|
||||||
# Force deprecations to raise an exception.
|
# Force deprecations to raise an exception.
|
||||||
# ActiveSupport::Deprecation.behavior = :raise
|
# ActiveSupport::Deprecation.behavior = :raise
|
||||||
|
|||||||
@@ -1,86 +1,114 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe 'Quill editor' do
|
RSpec.describe 'Quill editor' do
|
||||||
|
def lookup_editor(field:)
|
||||||
|
selector = ["##{field}_input.quill_editor", QuillEditor::SELECTOR].join(' ')
|
||||||
|
toolbar_selector = ["##{field}_input.quill_editor", QuillEditor::TOOLBAR_SELECTOR].join(' ')
|
||||||
|
QuillEditor.new(selector: selector, toolbar_selector: toolbar_selector)
|
||||||
|
end
|
||||||
|
|
||||||
let(:author) { Author.create!(email: 'some_email@example.com', name: 'John Doe', age: 30) }
|
let(:author) { Author.create!(email: 'some_email@example.com', name: 'John Doe', age: 30) }
|
||||||
let!(:post) { Post.create!(title: 'Test', author: author, description: 'Some content...') }
|
let!(:post) { Post.create!(title: 'Test', author: author, description: '') }
|
||||||
|
|
||||||
context 'with a Quill editor' do
|
context 'with a Quill editor' do
|
||||||
it 'initialize the editor' do
|
let(:editor) { lookup_editor(field: 'post_description') }
|
||||||
visit "/admin/posts/#{post.id}/edit"
|
|
||||||
|
|
||||||
%w[bold italic underline link].each do |button|
|
before do
|
||||||
expect(page).to have_css(".ql-toolbar button.ql-#{button}")
|
path = edit_admin_post_path(post)
|
||||||
end
|
Admin::Posts::EditPage.new(path: path).load
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adds some text to the description', :aggregate_failures do
|
||||||
expect(page).to have_css('#post_description[data-aa-quill-editor]')
|
expect(page).to have_css('#post_description[data-aa-quill-editor]')
|
||||||
expect(page).to have_css('#post_description_input .ql-editor', text: 'Some content...')
|
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 '<p>Some content...</p>'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds some text to the description' do
|
it 'adds some bold text to the description', :aggregate_failures do
|
||||||
visit "/admin/posts/#{post.id}/edit"
|
editor.toolbar_control(:bold)
|
||||||
|
editor << 'Some bold text'
|
||||||
|
|
||||||
find('#post_description_input .ql-editor').click
|
expect(editor.content_element).to have_content('Some bold text')
|
||||||
find('#post_description_input .ql-editor').base.send_keys('more text')
|
expect { find('[type="submit"]').click }
|
||||||
find('[type="submit"]').click
|
.to change { post.reload.description }.to '<p><strong>Some bold text</strong></p>'
|
||||||
|
|
||||||
expect(page).to have_content('was successfully updated')
|
|
||||||
expect(post.reload.description).to eq '<p>Some content...more text</p>'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds some bold text to the description' do
|
it 'adds some italic text to the description', :aggregate_failures do
|
||||||
visit "/admin/posts/#{post.id}/edit"
|
editor.toolbar_control(:italic)
|
||||||
|
editor << 'Some italic text'
|
||||||
|
|
||||||
find('#post_description_input .ql-editor').click
|
expect(editor.content_element).to have_content('Some italic text')
|
||||||
find('#post_description_input .ql-toolbar .ql-bold').click
|
expect { find('[type="submit"]').click }
|
||||||
find('#post_description_input .ql-editor').base.send_keys('more text')
|
.to change { post.reload.description }.to '<p><em>Some italic text</em></p>'
|
||||||
find('[type="submit"]').click
|
|
||||||
|
|
||||||
expect(post.reload.description).to eq '<p>Some content...<strong>more text</strong></p>'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds some italic text to the description' do
|
it 'adds some underline text to the description', :aggregate_failures do
|
||||||
visit "/admin/posts/#{post.id}/edit"
|
editor.toolbar_control(:underline)
|
||||||
|
editor << 'Some underline text'
|
||||||
|
|
||||||
find('#post_description_input .ql-editor').click
|
expect(editor.content_element).to have_content('Some underline text')
|
||||||
find('#post_description_input .ql-toolbar .ql-italic').click
|
expect { find('[type="submit"]').click }
|
||||||
find('#post_description_input .ql-editor').base.send_keys('more text')
|
.to change { post.reload.description }.to '<p><u>Some underline text</u></p>'
|
||||||
find('[type="submit"]').click
|
end
|
||||||
|
|
||||||
expect(post.reload.description).to eq '<p>Some content...<em>more text</em></p>'
|
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 = '<p><a href="Just a linkhttps://www.google.com" rel="noopener noreferrer" target="_blank">Just a link</a></p>'
|
||||||
|
expect { find('[type="submit"]').click }.to change { post.reload.description }.to html
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with 2 Quill editors' do
|
context 'with 2 Quill editors' do
|
||||||
it 'updates some HTML content for 2 fields' do
|
before do
|
||||||
visit "/admin/posts/#{post.id}/edit"
|
path = edit_admin_post_path(post)
|
||||||
|
Admin::Posts::EditPage.new(path: path).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"
|
||||||
|
|
||||||
|
editor2 = lookup_editor(field: 'post_summary')
|
||||||
|
editor2.clear.toolbar_control(:italic)
|
||||||
|
editor2 << "Some summary"
|
||||||
|
|
||||||
find('#post_description_input .ql-editor').click
|
|
||||||
find('#post_description_input .ql-toolbar .ql-bold').click
|
|
||||||
find('#post_description_input .ql-editor').base.send_keys('more text')
|
|
||||||
find('#post_summary_input .ql-editor').click
|
|
||||||
find('#post_summary_input .ql-toolbar .ql-italic').click
|
|
||||||
find('#post_summary_input .ql-editor').base.send_keys('Summary text')
|
|
||||||
find('[type="submit"]').click
|
find('[type="submit"]').click
|
||||||
post.reload
|
post.reload
|
||||||
|
|
||||||
expect(post.description).to eq '<p>Some content...<strong>more text</strong></p>'
|
expect(post.description).to eq '<p><strong>Some description</strong></p>'
|
||||||
expect(post.summary).to eq '<p><em>Summary text</em></p>'
|
expect(post.summary).to eq '<p><em>Some summary</em></p>'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a Quill editor in a nested resource' do
|
context 'with a Quill editor in a nested resource' do
|
||||||
it 'updates some HTML content of a new nested resource' do
|
before do
|
||||||
visit "/admin/authors/#{author.id}/edit"
|
path = edit_admin_author_path(author)
|
||||||
|
Admin::Authors::EditPage.new(path: path).load
|
||||||
|
end
|
||||||
|
|
||||||
expect(page).to have_css('.posts.has_many_container .ql-editor', text: 'Some content...')
|
it 'updates some HTML content of a new nested resource', :aggregate_failures do
|
||||||
find('.posts.has_many_container .has_many_add').click
|
find('.posts.has_many_container .has_many_add').click
|
||||||
expect(page).to have_css('.posts.has_many_container .ql-editor', count: 2)
|
expect(page).to have_css('.posts.has_many_container .ql-editor', count: 2)
|
||||||
|
|
||||||
|
editor = lookup_editor(field: 'author_posts_attributes_1_description')
|
||||||
|
editor << "Some post text"
|
||||||
|
|
||||||
fill_in('author[posts_attributes][1][title]', with: 'A new post')
|
fill_in('author[posts_attributes][1][title]', with: 'A new post')
|
||||||
find('#author_posts_attributes_1_description_input .ql-editor').base.send_keys('new post text')
|
|
||||||
find('[type="submit"]').click
|
find('[type="submit"]').click
|
||||||
|
|
||||||
expect(page).to have_content('was successfully updated')
|
expect(page).to have_content('was successfully updated')
|
||||||
expect(author.posts.last.description).to eq '<p>new post text</p>'
|
expect(author.posts.last.description).to eq '<p>Some post text</p>'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user