Commit ab47974c authored by Mark Lapierre's avatar Mark Lapierre

Update the blob viewer Create/Edit/Delete test

This change has two aims:
1. To fix some flakiness that recently appeared
2. To restore the test of creating a file via the blob viewer

- Uses specific predicate methods to check for content instead of
  checking the entire page. This also implicitly waits for loading to
  complete, which should make the test more reliable.
- Reverts Resource::File to create a new file via the blob viewer,
  after initializing the project with a readme.
- Removes some unused code.
- Adds a page object component for the flash notice that appears on
  many pages.
parent acce00c3
-# We currently only support `alert`, `notice`, `success`, 'toast' -# We currently only support `alert`, `notice`, `success`, 'toast'
- icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'}; - icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'};
.flash-container.flash-container-page.sticky .flash-container.flash-container-page.sticky{ data: { qa_selector: 'flash_container' } }
- flash.each do |key, value| - flash.each do |key, value|
- if key == 'toast' && value - if key == 'toast' && value
.js-toast-message{ data: { message: value } } .js-toast-message{ data: { message: value } }
......
.file-header-content .file-header-content
= blob_icon blob.mode, blob.name = blob_icon blob.mode, blob.name
%strong.file-title-name %strong.file-title-name{ data: { qa_selector: 'file_name_content' } }
= blob.name = blob.name
= copy_file_path_button(blob.path) = copy_file_path_button(blob.path)
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
= author_avatar(commit, size: 40, has_tooltip: false) = author_avatar(commit, size: 40, has_tooltip: false)
.commit-detail.flex-list .commit-detail.flex-list
.commit-content.qa-commit-content .commit-content{ data: { qa_selector: 'commit_content' } }
- if view_details && merge_request - if view_details && merge_request
= link_to commit.title, project_commit_path(project, commit.id, merge_request_iid: merge_request.iid), class: ["commit-row-message item-title js-onboarding-commit-item", ("font-italic" if commit.message.empty?)] = link_to commit.title, project_commit_path(project, commit.id, merge_request_iid: merge_request.iid), class: ["commit-row-message item-title js-onboarding-commit-item", ("font-italic" if commit.message.empty?)]
- else - else
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
= link_icon = link_icon
= i = i
- highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil - highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
.blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight } } .blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
%pre.code.highlight %pre.code.highlight
%code %code
= blob.present.highlight = blob.present.highlight
...@@ -403,6 +403,7 @@ module QA ...@@ -403,6 +403,7 @@ module QA
module Layout module Layout
autoload :Banner, 'qa/page/layout/banner' autoload :Banner, 'qa/page/layout/banner'
autoload :Flash, 'qa/page/layout/flash'
autoload :PerformanceBar, 'qa/page/layout/performance_bar' autoload :PerformanceBar, 'qa/page/layout/performance_bar'
end end
......
...@@ -13,11 +13,19 @@ module QA ...@@ -13,11 +13,19 @@ module QA
base.view 'app/views/shared/_commit_message_container.html.haml' do base.view 'app/views/shared/_commit_message_container.html.haml' do
element :commit_message, "text_area_tag 'commit_message'" # rubocop:disable QA/ElementWithPattern element :commit_message, "text_area_tag 'commit_message'" # rubocop:disable QA/ElementWithPattern
end end
base.view 'app/views/projects/commits/_commit.html.haml' do
element :commit_content
end
end end
def add_commit_message(message) def add_commit_message(message)
fill_in 'commit_message', with: message fill_in 'commit_message', with: message
end end
def has_commit_message?(text)
has_element?(:commit_content, text: text)
end
end end
end end
end end
......
...@@ -7,16 +7,25 @@ module QA ...@@ -7,16 +7,25 @@ module QA
include Shared::CommitMessage include Shared::CommitMessage
include Project::SubMenus::Settings include Project::SubMenus::Settings
include Project::SubMenus::Common include Project::SubMenus::Common
include Layout::Flash
view 'app/helpers/blob_helper.rb' do view 'app/helpers/blob_helper.rb' do
element :edit_button, "_('Edit')" # rubocop:disable QA/ElementWithPattern element :edit_button, "_('Edit')" # rubocop:disable QA/ElementWithPattern
element :delete_button, '_("Delete")' # rubocop:disable QA/ElementWithPattern element :delete_button, '_("Delete")' # rubocop:disable QA/ElementWithPattern
end end
view 'app/views/projects/blob/_header_content.html.haml' do
element :file_name_content
end
view 'app/views/projects/blob/_remove.html.haml' do view 'app/views/projects/blob/_remove.html.haml' do
element :delete_file_button, "button_tag 'Delete file'" # rubocop:disable QA/ElementWithPattern element :delete_file_button, "button_tag 'Delete file'" # rubocop:disable QA/ElementWithPattern
end end
view 'app/views/shared/_file_highlight.html.haml' do
element :file_content
end
def click_edit def click_edit
click_on 'Edit' click_on 'Edit'
end end
...@@ -28,6 +37,18 @@ module QA ...@@ -28,6 +37,18 @@ module QA
def click_delete_file def click_delete_file
click_on 'Delete file' click_on 'Delete file'
end end
def has_file?(name)
has_element?(:file_name_content, text: name)
end
def has_no_file?(name)
has_no_element?(:file_name_content, text: name)
end
def has_file_content?(text)
has_element?(:file_content, text: text)
end
end end
end end
end end
......
# frozen_string_literal: true
module QA
module Page
module Layout
module Flash
extend QA::Page::PageConcern
def self.included(base)
super
base.view 'app/views/layouts/_flash.html.haml' do
element :flash_container
end
end
def has_notice?(message)
within_element(:flash_container) do
has_text?(message)
end
end
end
end
end
end
...@@ -177,6 +177,10 @@ module QA ...@@ -177,6 +177,10 @@ module QA
has_element?(:file_name_content, text: file_name) has_element?(:file_name_content, text: file_name)
end end
def has_no_file?(file_name)
has_no_element?(:file_name_content, text: file_name)
end
def has_merge_button? def has_merge_button?
refresh refresh
......
...@@ -4,9 +4,11 @@ module QA ...@@ -4,9 +4,11 @@ module QA
module Page module Page
module Project module Project
class Show < Page::Base class Show < Page::Base
include Layout::Flash
include Page::Component::ClonePanel include Page::Component::ClonePanel
include Page::Component::Breadcrumbs include Page::Component::Breadcrumbs
include Page::Project::SubMenus::Settings include Page::Project::SubMenus::Settings
include Page::File::Shared::CommitMessage
view 'app/assets/javascripts/repository/components/preview/index.vue' do view 'app/assets/javascripts/repository/components/preview/index.vue' do
element :blob_viewer_content element :blob_viewer_content
...@@ -121,6 +123,12 @@ module QA ...@@ -121,6 +123,12 @@ module QA
end end
end end
def has_no_file?(name)
within_element(:file_tree_table) do
has_no_element?(:file_name_link, text: name)
end
end
def has_name?(name) def has_name?(name)
has_element?(:project_name_content, text: name) has_element?(:project_name_content, text: name)
end end
...@@ -129,10 +137,6 @@ module QA ...@@ -129,10 +137,6 @@ module QA
has_element?(:blob_viewer_content, text: text) has_element?(:blob_viewer_content, text: text)
end end
def last_commit_content
find_element(:commit_content).text
end
def new_merge_request def new_merge_request
wait_until(reload: true) do wait_until(reload: true) do
has_css?(element_selector_css(:create_merge_request)) has_css?(element_selector_css(:create_merge_request))
......
...@@ -13,6 +13,13 @@ module QA ...@@ -13,6 +13,13 @@ module QA
attribute :project do attribute :project do
Project.fabricate! do |resource| Project.fabricate! do |resource|
resource.name = 'project-with-new-file' resource.name = 'project-with-new-file'
# Creating the first file via the Wed IDE is tested in
# browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
# So here we want to use the old blob viewer, which is not
# available via the UI unless at least one file exists, which
# is why we create the project with a readme file.
resource.initialize_with_readme = true
end end
end end
...@@ -25,16 +32,13 @@ module QA ...@@ -25,16 +32,13 @@ module QA
def fabricate! def fabricate!
project.visit! project.visit!
Page::Project::Show.perform(&:create_first_new_file!) Page::Project::Show.perform(&:create_new_file!)
Page::Project::WebIDE::Edit.perform do |ide|
ide.add_file(@name, @content)
ide.commit_changes(@commit_message)
ide.go_to_project
end
Page::Project::Show.perform do |project| Page::File::Form.perform do |form|
project.click_file(@name) form.add_name(@name)
form.add_content(@content)
form.add_commit_message(@commit_message)
form.commit_changes
end end
end end
......
# frozen_string_literal: true # frozen_string_literal: true
module QA module QA
include HaveFileMatcher
RSpec.describe 'Create' do RSpec.describe 'Create' do
describe 'Files management' do describe 'Files management' do
it 'user creates, edits and deletes a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/451' do it 'user creates, edits and deletes a file via the Web', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/451' do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Flow::Login.sign_in
Page::Main::Login.perform(&:sign_in_using_credentials)
# Create # Create
file_name = 'QA Test - File name' file_name = 'QA Test - File name'
...@@ -18,9 +19,13 @@ module QA ...@@ -18,9 +19,13 @@ module QA
file.commit_message = commit_message_for_create file.commit_message = commit_message_for_create
end end
expect(page).to have_content(file_name) Page::File::Show.perform do |file|
expect(page).to have_content(file_content) aggregate_failures 'file details' do
expect(page).to have_content(commit_message_for_create) expect(file).to have_file(file_name)
expect(file).to have_file_content(file_content)
expect(file).to have_commit_message(commit_message_for_create)
end
end
# Edit # Edit
updated_file_content = 'QA Test - Updated file content' updated_file_content = 'QA Test - Updated file content'
...@@ -28,29 +33,37 @@ module QA ...@@ -28,29 +33,37 @@ module QA
Page::File::Show.perform(&:click_edit) Page::File::Show.perform(&:click_edit)
Page::File::Form.act do Page::File::Form.perform do |file|
remove_content file.remove_content
add_content(updated_file_content) file.add_content(updated_file_content)
add_commit_message(commit_message_for_update) file.add_commit_message(commit_message_for_update)
commit_changes file.commit_changes
end end
expect(page).to have_content('Your changes have been successfully committed.') Page::File::Show.perform do |file|
expect(page).to have_content(updated_file_content) aggregate_failures 'file details' do
expect(page).to have_content(commit_message_for_update) expect(file).to have_notice('Your changes have been successfully committed.')
expect(file).to have_file_content(updated_file_content)
expect(file).to have_commit_message(commit_message_for_update)
end
end
# Delete # Delete
commit_message_for_delete = 'QA Test - Delete file' commit_message_for_delete = 'QA Test - Delete file'
Page::File::Show.act do Page::File::Show.perform do |file|
click_delete file.click_delete
add_commit_message(commit_message_for_delete) file.add_commit_message(commit_message_for_delete)
click_delete_file file.click_delete_file
end end
expect(page).to have_content('The file has been successfully deleted.') Page::Project::Show.perform do |project|
expect(page).to have_content(commit_message_for_delete) aggregate_failures 'file details' do
expect(page).to have_no_content(file_name) expect(project).to have_notice('The file has been successfully deleted.')
expect(project).to have_commit_message(commit_message_for_delete)
expect(project).not_to have_file(file_name)
end
end
end end
end end
end end
......
...@@ -14,6 +14,7 @@ QA::Runtime::Browser.configure! ...@@ -14,6 +14,7 @@ QA::Runtime::Browser.configure!
QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes) if QA::Runtime::Env.runtime_scenario_attributes QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes) if QA::Runtime::Env.runtime_scenario_attributes
Dir[::File.join(__dir__, "support/helpers/*.rb")].sort.each { |f| require f } Dir[::File.join(__dir__, "support/helpers/*.rb")].sort.each { |f| require f }
Dir[::File.join(__dir__, "support/matchers/*.rb")].sort.each { |f| require f }
Dir[::File.join(__dir__, "support/shared_contexts/*.rb")].sort.each { |f| require f } Dir[::File.join(__dir__, "support/shared_contexts/*.rb")].sort.each { |f| require f }
Dir[::File.join(__dir__, "support/shared_examples/*.rb")].sort.each { |f| require f } Dir[::File.join(__dir__, "support/shared_examples/*.rb")].sort.each { |f| require f }
......
# frozen_string_literal: true
module HaveFileMatcher
RSpec::Matchers.define :have_file do |file|
match do |page_object|
page_object.has_file?(file)
end
match_when_negated do |page_object|
page_object.has_no_file?(file)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment