summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
Diffstat (limited to 'qa')
-rw-r--r--qa/README.md19
-rw-r--r--qa/Rakefile5
-rw-r--r--qa/qa.rb5
-rw-r--r--qa/qa/page/base.rb4
-rw-r--r--qa/qa/page/component/confirm_modal.rb25
-rw-r--r--qa/qa/page/component/select2.rb4
-rw-r--r--qa/qa/page/dashboard/projects.rb8
-rw-r--r--qa/qa/page/file/edit.rb13
-rw-r--r--qa/qa/page/file/form.rb27
-rw-r--r--qa/qa/page/file/shared/commit_button.rb21
-rw-r--r--qa/qa/page/file/shared/editor.rb33
-rw-r--r--qa/qa/page/file/show.rb2
-rw-r--r--qa/qa/page/merge_request/show.rb8
-rw-r--r--qa/qa/page/project/issue/show.rb49
-rw-r--r--qa/qa/page/project/pipeline/index.rb2
-rw-r--r--qa/qa/page/project/settings/advanced.rb16
-rw-r--r--qa/qa/page/project/settings/main.rb2
-rw-r--r--qa/qa/page/project/sub_menus/project.rb29
-rw-r--r--qa/qa/page/project/sub_menus/settings.rb9
-rw-r--r--qa/qa/page/settings/common.rb2
-rw-r--r--qa/qa/resource/api_fabricator.rb7
-rw-r--r--qa/qa/resource/group.rb4
-rw-r--r--qa/qa/resource/issue.rb17
-rw-r--r--qa/qa/resource/label.rb21
-rw-r--r--qa/qa/resource/merge_request_from_fork.rb2
-rw-r--r--qa/qa/resource/project.rb34
-rw-r--r--qa/qa/resource/project_milestone.rb15
-rw-r--r--qa/qa/resource/sandbox.rb4
-rw-r--r--qa/qa/resource/user.rb2
-rw-r--r--qa/qa/runtime/address.rb2
-rw-r--r--qa/qa/runtime/api/client.rb19
-rw-r--r--qa/qa/runtime/browser.rb19
-rw-r--r--qa/qa/runtime/env.rb23
-rw-r--r--qa/qa/service/shellout.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb75
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb57
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/login_via_oauth_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb80
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb59
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb2
-rw-r--r--qa/qa/support/api.rb5
-rw-r--r--qa/qa/support/page/logging.rb2
-rw-r--r--qa/qa/tools/generate_perf_testdata.rb185
-rw-r--r--qa/spec/page/logging_spec.rb4
-rw-r--r--qa/spec/runtime/api/client_spec.rb36
-rw-r--r--qa/spec/runtime/env_spec.rb6
-rw-r--r--qa/spec/specs/runner_spec.rb68
56 files changed, 807 insertions, 264 deletions
diff --git a/qa/README.md b/qa/README.md
index ef6f202464d..124a79a36b4 100644
--- a/qa/README.md
+++ b/qa/README.md
@@ -34,8 +34,23 @@ using `package-and-qa` manual action, to test if everything works fine.
## How can I use it?
-You can use GitLab QA to exercise tests on any live instance! For example, the
-following call would login to a local [GDK] instance and run all specs in
+You can use GitLab QA to exercise tests on any live instance! If you don't
+have an instance available you can follow the instructions below to use
+the [GitLab Development Kit (GDK)][GDK].
+This is the recommended option if you would like to contribute to the tests.
+
+### Run the end-to-end tests in a local development environment
+
+Follow the GDK instructions to [prepare](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/prepare.md)
+and [install](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/set-up-gdk.md)
+your local GitLab development environment.
+
+Once you have GDK running, switch to the `qa` directory. E.g., if you setup
+GDK to develop in the main `gitlab-ce` repo, the GitLab source code will be
+in a `gitlab` directory and so the end-to-end test code will be in `gitlab/qa`.
+
+From there you can run the tests. For example, the
+following call would login to the GDK instance and run all specs in
`qa/specs/features`:
```
diff --git a/qa/Rakefile b/qa/Rakefile
index 7ac018f7286..7ba8a6d68ba 100644
--- a/qa/Rakefile
+++ b/qa/Rakefile
@@ -13,8 +13,9 @@ task :delete_subgroups do
end
desc "Generate Performance Testdata"
-task :generate_perf_testdata do
- QA::Tools::GeneratePerfTestdata.new.run
+task :generate_perf_testdata, :type do |t, args|
+ args.with_defaults(type: :all)
+ QA::Tools::GeneratePerfTestdata.new.method(args[:type]).call
end
desc "Run artillery load tests"
diff --git a/qa/qa.rb b/qa/qa.rb
index 944dcc31917..10d44b6f6d9 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -162,9 +162,12 @@ module QA
module File
autoload :Form, 'qa/page/file/form'
autoload :Show, 'qa/page/file/show'
+ autoload :Edit, 'qa/page/file/edit'
module Shared
autoload :CommitMessage, 'qa/page/file/shared/commit_message'
+ autoload :CommitButton, 'qa/page/file/shared/commit_button'
+ autoload :Editor, 'qa/page/file/shared/editor'
end
end
@@ -218,6 +221,7 @@ module QA
autoload :Operations, 'qa/page/project/sub_menus/operations'
autoload :Repository, 'qa/page/project/sub_menus/repository'
autoload :Settings, 'qa/page/project/sub_menus/settings'
+ autoload :Project, 'qa/page/project/sub_menus/project'
end
module Issue
@@ -323,6 +327,7 @@ module QA
autoload :DropdownFilter, 'qa/page/component/dropdown_filter'
autoload :UsersSelect, 'qa/page/component/users_select'
autoload :Note, 'qa/page/component/note'
+ autoload :ConfirmModal, 'qa/page/component/confirm_modal'
module Issuable
autoload :Common, 'qa/page/component/issuable/common'
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index d247a273637..d0fe2987b0a 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -197,6 +197,10 @@ module QA
views.map(&:elements).flatten
end
+ def send_keys_to_element(name, keys)
+ find_element(name).send_keys(keys)
+ end
+
class DSL
attr_reader :views
diff --git a/qa/qa/page/component/confirm_modal.rb b/qa/qa/page/component/confirm_modal.rb
new file mode 100644
index 00000000000..355e2783fb7
--- /dev/null
+++ b/qa/qa/page/component/confirm_modal.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Component
+ module ConfirmModal
+ def self.included(base)
+ base.view 'app/views/shared/_confirm_modal.html.haml' do
+ element :confirm_modal
+ element :confirm_input
+ element :confirm_button
+ end
+ end
+
+ def fill_confirmation_text(text)
+ fill_element :confirm_input, text
+ end
+
+ def click_confirm_button
+ click_element :confirm_button
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/component/select2.rb b/qa/qa/page/component/select2.rb
index e40bc4b1d3e..85d4abcde9b 100644
--- a/qa/qa/page/component/select2.rb
+++ b/qa/qa/page/component/select2.rb
@@ -18,6 +18,10 @@ module QA
find('.select2-input').set(item_text)
select_item(item_text)
end
+
+ def expand_select_list
+ find('span.select2-arrow').click
+ end
end
end
end
diff --git a/qa/qa/page/dashboard/projects.rb b/qa/qa/page/dashboard/projects.rb
index 7ab8ee39f72..0c23d7cffbb 100644
--- a/qa/qa/page/dashboard/projects.rb
+++ b/qa/qa/page/dashboard/projects.rb
@@ -5,7 +5,7 @@ module QA
module Dashboard
class Projects < Page::Base
view 'app/views/shared/projects/_search_form.html.haml' do
- element :form_filter_by_name, /form_tag.+id: 'project-filter-form'/ # rubocop:disable QA/ElementWithPattern
+ element :project_filter_form, required: true
end
def go_to_project(name)
@@ -14,10 +14,14 @@ module QA
find_link(text: name).click
end
+ def self.path
+ '/'
+ end
+
private
def filter_by_name(name)
- page.within('form#project-filter-form') do
+ within_element(:project_filter_form) do
fill_in :name, with: name
end
end
diff --git a/qa/qa/page/file/edit.rb b/qa/qa/page/file/edit.rb
new file mode 100644
index 00000000000..3a4a1837b1c
--- /dev/null
+++ b/qa/qa/page/file/edit.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module File
+ class Edit < Page::Base
+ include Shared::CommitMessage
+ include Shared::CommitButton
+ include Shared::Editor
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/file/form.rb b/qa/qa/page/file/form.rb
index e42de7d65c5..a6251f185f9 100644
--- a/qa/qa/page/file/form.rb
+++ b/qa/qa/page/file/form.rb
@@ -6,14 +6,11 @@ module QA
class Form < Page::Base
include Shared::CommitMessage
include Page::Component::DropdownFilter
+ include Shared::CommitButton
+ include Shared::Editor
view 'app/views/projects/blob/_editor.html.haml' do
element :file_name, "text_field_tag 'file_name'" # rubocop:disable QA/ElementWithPattern
- element :editor, '#editor' # rubocop:disable QA/ElementWithPattern
- end
-
- view 'app/views/projects/_commit_button.html.haml' do
- element :commit_changes, "button_tag 'Commit changes'" # rubocop:disable QA/ElementWithPattern
end
view 'app/views/projects/blob/_template_selectors.html.haml' do
@@ -28,20 +25,6 @@ module QA
fill_in 'file_name', with: name
end
- def add_content(content)
- text_area.set content
- end
-
- def remove_content
- text_area.send_keys([:command, 'a'], :backspace)
- end
-
- def commit_changes
- click_on 'Commit changes'
-
- finished_loading?
- end
-
def select_template(template_type, template)
click_element :template_type_dropdown
click_link template_type
@@ -60,12 +43,6 @@ module QA
end
filter_and_select template
end
-
- private
-
- def text_area
- find('#editor>textarea', visible: false)
- end
end
end
end
diff --git a/qa/qa/page/file/shared/commit_button.rb b/qa/qa/page/file/shared/commit_button.rb
new file mode 100644
index 00000000000..d8e751dd7b6
--- /dev/null
+++ b/qa/qa/page/file/shared/commit_button.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module File
+ module Shared
+ module CommitButton
+ def self.included(base)
+ base.view 'app/views/projects/_commit_button.html.haml' do
+ element :commit_button
+ end
+ end
+
+ def commit_changes
+ click_element(:commit_button)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/file/shared/editor.rb b/qa/qa/page/file/shared/editor.rb
new file mode 100644
index 00000000000..448c09cfbca
--- /dev/null
+++ b/qa/qa/page/file/shared/editor.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module File
+ module Shared
+ module Editor
+ def self.included(base)
+ base.view 'app/views/projects/blob/_editor.html.haml' do
+ element :editor
+ end
+ end
+
+ def add_content(content)
+ text_area.set content
+ end
+
+ def remove_content
+ text_area.send_keys([:command, 'a'], :backspace)
+ end
+
+ private
+
+ def text_area
+ within_element :editor do
+ find('textarea', visible: false)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/file/show.rb b/qa/qa/page/file/show.rb
index eaf88c6e69e..92f9181f99d 100644
--- a/qa/qa/page/file/show.rb
+++ b/qa/qa/page/file/show.rb
@@ -5,6 +5,8 @@ module QA
module File
class Show < Page::Base
include Shared::CommitMessage
+ include Project::SubMenus::Settings
+ include Project::SubMenus::Common
view 'app/helpers/blob_helper.rb' do
element :edit_button, "_('Edit')" # rubocop:disable QA/ElementWithPattern
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index 5aef868a805..6a415b56e50 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -111,6 +111,14 @@ module QA
end
end
+ def has_title?(title)
+ has_element?(:title, text: title)
+ end
+
+ def has_description?(description)
+ has_element?(:description, text: description)
+ end
+
def merge!
# The merge button is disabled on load
wait do
diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb
index 9df3db1bba0..b59540d0377 100644
--- a/qa/qa/page/project/issue/show.rb
+++ b/qa/qa/page/project/issue/show.rb
@@ -8,11 +8,6 @@ module QA
include Page::Component::Issuable::Common
include Page::Component::Note
- view 'app/views/shared/notes/_form.html.haml' do
- element :new_note_form, 'new-note' # rubocop:disable QA/ElementWithPattern
- element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern
- end
-
view 'app/assets/javascripts/notes/components/comment_form.vue' do
element :comment_button
element :comment_input
@@ -27,9 +22,25 @@ module QA
element :noteable_note_item
end
+ view 'app/helpers/dropdowns_helper.rb' do
+ element :dropdown_input_field
+ end
+
+ view 'app/views/shared/notes/_form.html.haml' do
+ element :new_note_form, 'new-note' # rubocop:disable QA/ElementWithPattern
+ element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern
+ end
+
+ view 'app/views/shared/issuable/_sidebar.html.haml' do
+ element :labels_block
+ element :edit_link_labels
+ element :dropdown_menu_labels
+ end
+
# Adds a comment to an issue
# attachment option should be an absolute path
- def comment(text, attachment: nil)
+ def comment(text, attachment: nil, filter: :all_activities)
+ method("select_#{filter}_filter").call
fill_element :comment_input, text
unless attachment.nil?
@@ -46,6 +57,10 @@ module QA
end
end
+ def select_all_activities_filter
+ select_filter_with_text('Show all activity')
+ end
+
def select_comments_only_filter
select_filter_with_text('Show comments only')
end
@@ -54,8 +69,26 @@ module QA
select_filter_with_text('Show history only')
end
- def select_all_activities_filter
- select_filter_with_text('Show all activity')
+ def select_labels_and_refresh(labels)
+ click_element(:edit_link_labels)
+
+ labels.each do |label|
+ within_element(:dropdown_menu_labels, text: label) do
+ send_keys_to_element(:dropdown_input_field, [label, :enter])
+ end
+ end
+
+ click_body
+
+ labels.each do |label|
+ has_element?(:labels_block, text: label)
+ end
+
+ refresh
+ end
+
+ def text_of_labels_block
+ find_element(:labels_block)
end
private
diff --git a/qa/qa/page/project/pipeline/index.rb b/qa/qa/page/project/pipeline/index.rb
index 68850d989b1..fae7818f871 100644
--- a/qa/qa/page/project/pipeline/index.rb
+++ b/qa/qa/page/project/pipeline/index.rb
@@ -4,7 +4,7 @@ module QA::Page
module Project::Pipeline
class Index < QA::Page::Base
view 'app/assets/javascripts/pipelines/components/pipeline_url.vue' do
- element :pipeline_link, 'class="js-pipeline-url-link"' # rubocop:disable QA/ElementWithPattern
+ element :pipeline_link, 'class="js-pipeline-url-link' # rubocop:disable QA/ElementWithPattern
end
def click_on_latest_pipeline
diff --git a/qa/qa/page/project/settings/advanced.rb b/qa/qa/page/project/settings/advanced.rb
index 75530832860..ab4e3d757b6 100644
--- a/qa/qa/page/project/settings/advanced.rb
+++ b/qa/qa/page/project/settings/advanced.rb
@@ -5,9 +5,13 @@ module QA
module Project
module Settings
class Advanced < Page::Base
+ include Component::Select2
+ include Component::ConfirmModal
+
view 'app/views/projects/edit.html.haml' do
element :project_path_field
element :change_path_button
+ element :transfer_button
end
def update_project_path_to(path)
@@ -22,6 +26,18 @@ module QA
def click_change_path_button
click_element :change_path_button
end
+
+ def select_transfer_option(namespace)
+ search_and_select(namespace)
+ end
+
+ def transfer_project!(project_name, namespace)
+ expand_select_list
+ select_transfer_option(namespace)
+ click_element(:transfer_button)
+ fill_confirmation_text(project_name)
+ click_confirm_button
+ end
end
end
end
diff --git a/qa/qa/page/project/settings/main.rb b/qa/qa/page/project/settings/main.rb
index d1f3b15f950..dbbe62e3b1d 100644
--- a/qa/qa/page/project/settings/main.rb
+++ b/qa/qa/page/project/settings/main.rb
@@ -6,6 +6,8 @@ module QA
module Settings
class Main < Page::Base
include Common
+ include Component::Select2
+ include SubMenus::Project
view 'app/views/projects/edit.html.haml' do
element :advanced_settings
diff --git a/qa/qa/page/project/sub_menus/project.rb b/qa/qa/page/project/sub_menus/project.rb
new file mode 100644
index 00000000000..5e0ee3c274a
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/project.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module Project
+ include Common
+
+ def self.included(base)
+ base.class_eval do
+ view 'app/views/layouts/nav/sidebar/_project.html.haml' do
+ element :link_project
+ end
+ end
+ end
+
+ def click_project
+ retry_on_exception do
+ within_sidebar do
+ click_element(:link_project)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/settings.rb b/qa/qa/page/project/sub_menus/settings.rb
index 22743ebd0a1..88b45ec55ae 100644
--- a/qa/qa/page/project/sub_menus/settings.rb
+++ b/qa/qa/page/project/sub_menus/settings.rb
@@ -10,6 +10,7 @@ module QA
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :settings_item
element :link_members_settings
+ element :general_settings_link
end
end
end
@@ -38,6 +39,14 @@ module QA
end
end
+ def go_to_general_settings
+ hover_settings do
+ within_submenu do
+ click_element :general_settings_link
+ end
+ end
+ end
+
def click_settings
within_sidebar do
click_on 'Settings'
diff --git a/qa/qa/page/settings/common.rb b/qa/qa/page/settings/common.rb
index 8cd0b6bb49c..bede3fde105 100644
--- a/qa/qa/page/settings/common.rb
+++ b/qa/qa/page/settings/common.rb
@@ -11,7 +11,7 @@ module QA
within_element(element_name) do
# Because it is possible to click the button before the JS toggle code is bound
wait(reload: false) do
- click_button 'Expand' unless first('button', text: 'Collapse')
+ click_button 'Expand' unless has_css?('button', text: 'Collapse')
has_content?('Collapse')
end
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb
index de04467ff5b..d1d75b6179e 100644
--- a/qa/qa/resource/api_fabricator.rb
+++ b/qa/qa/resource/api_fabricator.rb
@@ -13,6 +13,8 @@ module QA
ResourceURLMissingError = Class.new(RuntimeError)
attr_reader :api_resource, :api_response
+ attr_writer :api_client
+ attr_accessor :user
def api_support?
respond_to?(:api_get_path) &&
@@ -29,9 +31,12 @@ module QA
end
def eager_load_api_client!
+ return unless api_client.nil?
+
api_client.tap do |client|
# Eager-load the API client so that the personal token creation isn't
# taken in account in the actual resource creation timing.
+ client.user = user
client.personal_access_token
end
end
@@ -76,7 +81,7 @@ module QA
def api_client
@api_client ||= begin
- Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http'))
+ Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http'), user: user)
end
end
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index 0b567a474c8..44d9dc8f296 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -67,6 +67,10 @@ module QA
visibility: 'public'
}
end
+
+ def full_path
+ sandbox.path + ' / ' + path
+ end
end
end
end
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index 2c2f27fe231..9c57a0f5afb 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -12,6 +12,8 @@ module QA
end
end
+ attribute :id
+ attribute :labels
attribute :title
def fabricate!
@@ -25,6 +27,21 @@ module QA
page.create_new_issue
end
end
+
+ def api_get_path
+ "/projects/#{project.id}/issues/#{id}"
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/issues"
+ end
+
+ def api_post_body
+ {
+ labels: [labels],
+ title: title
+ }
+ end
end
end
end
diff --git a/qa/qa/resource/label.rb b/qa/qa/resource/label.rb
index 7c899db31f3..3750725c440 100644
--- a/qa/qa/resource/label.rb
+++ b/qa/qa/resource/label.rb
@@ -34,6 +34,27 @@ module QA
page.click_label_create_button
end
end
+
+ def resource_web_url(resource)
+ super
+ rescue ResourceURLMissingError
+ # this particular resource does not expose a web_url property
+ end
+
+ def api_get_path
+ raise NotImplementedError, "The Labels API doesn't expose a single-resource endpoint so this method cannot be properly implemented."
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/labels"
+ end
+
+ def api_post_body
+ {
+ color: @color,
+ name: @title
+ }
+ end
end
end
end
diff --git a/qa/qa/resource/merge_request_from_fork.rb b/qa/qa/resource/merge_request_from_fork.rb
index 5d20a6e9c75..6c9a096289b 100644
--- a/qa/qa/resource/merge_request_from_fork.rb
+++ b/qa/qa/resource/merge_request_from_fork.rb
@@ -21,7 +21,7 @@ module QA
def fabricate!
populate(:push)
- fork.visit!
+ fork.project.visit!
Page::Project::Show.perform(&:new_merge_request)
Page::MergeRequest::New.perform(&:create_merge_request)
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index d706439a891..c0a6004fe27 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -11,14 +11,20 @@ module QA
attribute :id
attribute :name
+ attribute :add_name_uuid
attribute :description
+ attribute :standalone
attribute :group do
Group.fabricate!
end
attribute :path_with_namespace do
- "#{group.sandbox.path}/#{group.path}/#{name}" if group
+ "#{sandbox_path}#{group.path}/#{name}" if group
+ end
+
+ def sandbox_path
+ group.respond_to?('sandbox') ? "#{group.sandbox.path}/" : ''
end
attribute :repository_ssh_location do
@@ -34,18 +40,21 @@ module QA
end
def initialize
+ @add_name_uuid = true
+ @standalone = false
@description = 'My awesome project'
@initialize_with_readme = false
end
def name=(raw_name)
- @name = "#{raw_name}-#{SecureRandom.hex(8)}"
+ @name = @add_name_uuid ? "#{raw_name}-#{SecureRandom.hex(8)}" : raw_name
end
def fabricate!
- group.visit!
-
- Page::Group::Show.perform(&:go_to_new_project)
+ unless @standalone
+ group.visit!
+ Page::Group::Show.perform(&:go_to_new_project)
+ end
Page::Project::New.perform do |page|
page.choose_test_namespace
@@ -67,19 +76,28 @@ module QA
"/projects/#{CGI.escape(path_with_namespace)}"
end
+ def api_get_archive_path(type = 'tar.gz')
+ "#{api_get_path}/repository/archive.#{type}"
+ end
+
def api_post_path
'/projects'
end
def api_post_body
- {
- namespace_id: group.id,
- path: name,
+ post_body = {
name: name,
description: description,
visibility: 'public',
initialize_with_readme: @initialize_with_readme
}
+
+ unless @standalone
+ post_body[:namespace_id] = group.id
+ post_body[:path] = name
+ end
+
+ post_body
end
private
diff --git a/qa/qa/resource/project_milestone.rb b/qa/qa/resource/project_milestone.rb
index 8ace75f695a..70640eac095 100644
--- a/qa/qa/resource/project_milestone.rb
+++ b/qa/qa/resource/project_milestone.rb
@@ -31,6 +31,21 @@ module QA
milestone_new.click_milestone_create_button
end
end
+
+ def api_get_path
+ "/projects/#{project.id}/milestones/#{id}"
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/milestones"
+ end
+
+ def api_post_body
+ {
+ description: @description,
+ title: @title
+ }
+ end
end
end
end
diff --git a/qa/qa/resource/sandbox.rb b/qa/qa/resource/sandbox.rb
index 942eea5cc40..e2b1c4c0831 100644
--- a/qa/qa/resource/sandbox.rb
+++ b/qa/qa/resource/sandbox.rb
@@ -44,6 +44,10 @@ module QA
"/groups/#{path}"
end
+ def api_members_path
+ "#{api_get_path}/members"
+ end
+
def api_post_path
'/groups'
end
diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb
index 6c5e91b6488..eec46f46d99 100644
--- a/qa/qa/resource/user.rb
+++ b/qa/qa/resource/user.rb
@@ -88,7 +88,7 @@ module QA
}.merge(ldap_post_body)
end
- def self.fabricate_or_use(username, password)
+ def self.fabricate_or_use(username = nil, password = nil)
if Runtime::Env.signup_disabled?
self.new.tap do |user|
user.username = username
diff --git a/qa/qa/runtime/address.rb b/qa/qa/runtime/address.rb
index 98d042fb43a..c622051bb6d 100644
--- a/qa/qa/runtime/address.rb
+++ b/qa/qa/runtime/address.rb
@@ -5,7 +5,7 @@ module QA
class Address
attr_reader :address
- def initialize(instance, page = nil)
+ def initialize(instance, page)
@instance = instance
@address = host + (page.is_a?(String) ? page : page&.path)
end
diff --git a/qa/qa/runtime/api/client.rb b/qa/qa/runtime/api/client.rb
index 40a3bc85195..663be27a849 100644
--- a/qa/qa/runtime/api/client.rb
+++ b/qa/qa/runtime/api/client.rb
@@ -6,31 +6,34 @@ module QA
module Runtime
module API
class Client
- attr_reader :address
+ attr_reader :address, :user
- def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true)
+ def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true, user: nil)
@address = address
@personal_access_token = personal_access_token
@is_new_session = is_new_session
+ @user = user
end
def personal_access_token
@personal_access_token ||= begin
# you can set the environment variable GITLAB_QA_ACCESS_TOKEN
# to use a specific access token rather than create one from the UI
- Runtime::Env.personal_access_token ||= create_personal_access_token
+ # unless a specific user has been passed
+ @user.nil? ? Runtime::Env.personal_access_token ||= create_personal_access_token : create_personal_access_token
end
end
private
def create_personal_access_token
- Runtime::Browser.visit(@address, Page::Main::Login) if @is_new_session
- do_create_personal_access_token
- end
+ Page::Main::Menu.perform(&:sign_out) if @is_new_session && Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
+
+ unless Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
+ Runtime::Browser.visit(@address, Page::Main::Login)
+ Page::Main::Login.perform { |login| login.sign_in_using_credentials(@user) }
+ end
- def do_create_personal_access_token
- Page::Main::Login.perform(&:sign_in_using_credentials)
Resource::PersonalAccessToken.fabricate!.access_token
end
end
diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb
index 3bf4b3bbbfb..ed0779b93cc 100644
--- a/qa/qa/runtime/browser.rb
+++ b/qa/qa/runtime/browser.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'rspec/core'
+require 'rspec/expectations'
require 'capybara/rspec'
require 'capybara-screenshot/rspec'
require 'selenium-webdriver'
@@ -27,13 +28,12 @@ module QA
# In case of an address that is a symbol we will try to guess address
# based on `Runtime::Scenario#something_address`.
#
- def visit(address, page = nil, &block)
- Browser::Session.new(address, page).perform(&block)
+ def visit(address, page_class, &block)
+ Browser::Session.new(address, page_class).perform(&block)
end
- def self.visit(address, page = nil, &block)
- new.visit(address, page, &block)
- page.validate_elements_present!
+ def self.visit(address, page_class, &block)
+ new.visit(address, page_class, &block)
end
def self.configure!
@@ -128,8 +128,11 @@ module QA
class Session
include Capybara::DSL
- def initialize(instance, page = nil)
- @session_address = Runtime::Address.new(instance, page)
+ attr_reader :page_class
+
+ def initialize(instance, page_class)
+ @session_address = Runtime::Address.new(instance, page_class)
+ @page_class = page_class
end
def url
@@ -139,6 +142,8 @@ module QA
def perform(&block)
visit(url)
+ page_class.validate_elements_present!
+
if QA::Runtime::Env.qa_cookies
browser = Capybara.current_session.driver.browser
QA::Runtime::Env.qa_cookies.each do |cookie|
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 82510dfa03c..96f337dc081 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -10,13 +10,26 @@ module QA
# The environment variables used to indicate if the environment under test
# supports the given feature
SUPPORTED_FEATURES = {
- git_protocol_v2: 'QA_CAN_TEST_GIT_PROTOCOL_V2'
+ git_protocol_v2: 'QA_CAN_TEST_GIT_PROTOCOL_V2',
+ admin: 'QA_CAN_TEST_ADMIN_FEATURES'
}.freeze
def supported_features
SUPPORTED_FEATURES
end
+ def admin_password
+ ENV['GITLAB_ADMIN_PASSWORD']
+ end
+
+ def admin_username
+ ENV['GITLAB_ADMIN_USERNAME']
+ end
+
+ def admin_personal_access_token
+ ENV['GITLAB_QA_ADMIN_ACCESS_TOKEN']
+ end
+
def debug?
enabled?(ENV['QA_DEBUG'], default: false)
end
@@ -92,14 +105,6 @@ module QA
ENV['GITLAB_PASSWORD']
end
- def admin_username
- ENV['GITLAB_ADMIN_USERNAME']
- end
-
- def admin_password
- ENV['GITLAB_ADMIN_PASSWORD']
- end
-
def github_username
ENV['GITHUB_USERNAME']
end
diff --git a/qa/qa/service/shellout.rb b/qa/qa/service/shellout.rb
index 7065ab0e7f3..217df669db3 100644
--- a/qa/qa/service/shellout.rb
+++ b/qa/qa/service/shellout.rb
@@ -19,7 +19,7 @@ module QA
Open3.popen2e(*command) do |stdin, out, wait|
stdin.puts(stdin_data) if stdin_data
stdin.close if stdin_data
- out.each { |line| puts line }
+ out.each_char { |char| print char }
if wait.value.exited? && wait.value.exitstatus.nonzero?
raise CommandError, "Command `#{command}` failed!"
diff --git a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
new file mode 100644
index 00000000000..3fe04e8b835
--- /dev/null
+++ b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'securerandom'
+require 'digest'
+
+module QA
+ context 'Create' do
+ describe 'Compare archives of different user projects with the same name and check they\'re different' do
+ include Support::Api
+
+ before(:all) do
+ @project_name = "project-archive-download-#{SecureRandom.hex(8)}"
+ @archive_types = %w(tar.gz tar.bz2 tar zip)
+ @users = {
+ user1: { username: Runtime::Env.gitlab_qa_username_1, password: Runtime::Env.gitlab_qa_password_1 },
+ user2: { username: Runtime::Env.gitlab_qa_username_2, password: Runtime::Env.gitlab_qa_password_2 }
+ }
+
+ @users.each do |_, user_info|
+ user_info[:user] = Resource::User.fabricate_or_use(user_info[:username], user_info[:password])
+ user_info[:api_client] = Runtime::API::Client.new(:gitlab, user: user_info[:user])
+ user_info[:api_client].personal_access_token
+ user_info[:project] = create_project(user_info[:user], user_info[:api_client], @project_name)
+ Page::Main::Menu.perform(&:sign_out)
+ end
+ end
+
+ it 'download archives of each user project then check they are different' do
+ archive_checksums = {}
+
+ @users.each do |user_key, user_info|
+ archive_checksums[user_key] = {}
+
+ @archive_types.each do |type|
+ archive_path = download_project_archive_via_api(user_info[:api_client], user_info[:project], type).path
+ archive_checksums[user_key][type] = Digest::MD5.hexdigest(File.read(archive_path))
+ end
+ end
+
+ QA::Runtime::Logger.debug("Archive checksums are #{archive_checksums}")
+
+ expect(archive_checksums[:user1]).not_to include(archive_checksums[:user2])
+ end
+
+ def create_project(user, api_client, project_name)
+ project = Resource::Project.fabricate! do |project|
+ project.standalone = true
+ project.add_name_uuid = false
+ project.name = project_name
+ project.path_with_namespace = "#{user.name}/#{project_name}"
+ project.user = user
+ project.api_client = api_client
+ end
+
+ Resource::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.file_name = 'README.md'
+ push.file_content = '# This is a test project'
+ push.commit_message = 'Add README.md'
+ push.user = user
+ end
+
+ project
+ end
+
+ def download_project_archive_via_api(api_client, project, type = 'tar.gz')
+ get_project_archive_zip = Runtime::API::Request.new(api_client, project.api_get_archive_path(type))
+ project_archive_download = get(get_project_archive_zip.url, raw_response: true)
+ expect(project_archive_download.code).to eq(200)
+
+ project_archive_download.file
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
new file mode 100644
index 00000000000..a9de64e357a
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Manage' do
+ describe 'Project transfer between groups' do
+ it 'user transfers a project between groups' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ source_group = Resource::Group.fabricate! do |group|
+ group.path = 'source-group'
+ end
+
+ target_group = Resource::Group.fabricate! do |group|
+ group.path = 'target-group'
+ end
+
+ project = Resource::Project.fabricate! do |project|
+ project.group = source_group
+ project.name = 'transfer-project'
+ project.initialize_with_readme = true
+ end
+
+ project.visit!
+
+ Page::Project::Show.perform do |project|
+ project.click_file('README.md')
+ end
+
+ Page::File::Show.perform(&:click_edit)
+
+ edited_readme_content = 'Here is the edited content.'
+
+ Page::File::Edit.perform do |file|
+ file.remove_content
+ file.add_content(edited_readme_content)
+ file.commit_changes
+ end
+
+ Page::File::Show.perform(&:go_to_general_settings)
+
+ Page::Project::Settings::Main.perform(&:expand_advanced_settings)
+
+ Page::Project::Settings::Advanced.perform do |advanced|
+ advanced.transfer_project!(project.name, target_group.full_path)
+ end
+
+ Page::Project::Settings::Main.perform(&:click_project)
+
+ Page::Project::Show.perform do |project|
+ expect(project).to have_text(target_group.path)
+ expect(project).to have_text(edited_readme_content)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/login_via_oauth_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_oauth_spec.rb
index 15cd59f041b..a118176eb8a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/login_via_oauth_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_oauth_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module QA
- # https://gitlab.com/gitlab-org/quality/nightly/issues/100
- context 'Manage', :orchestrated, :oauth, :quarantine do
+ context 'Manage', :orchestrated, :oauth do
describe 'OAuth login' do
it 'User logs in to GitLab with GitHub OAuth' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
index fa779bd1f4e..4478ea41662 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
@@ -9,7 +9,7 @@ module QA
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
- Resource::Issue.fabricate! do |issue|
+ Resource::Issue.fabricate_via_browser_ui! do |issue|
issue.title = issue_title
end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
index 9b083d59a5e..1eea3efec7f 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
@@ -23,7 +23,6 @@ module QA
create_issue
Page::Project::Issue::Show.perform do |show|
- show.select_all_activities_filter
show.comment('See attached banana for scale', attachment: file_to_attach)
show.refresh
@@ -43,7 +42,7 @@ module QA
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
- Resource::Issue.fabricate! do |issue|
+ Resource::Issue.fabricate_via_browser_ui! do |issue|
issue.title = issue_title
end
end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
index c0d597af076..ad2773b41ac 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
@@ -9,16 +9,15 @@ module QA
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
- Resource::Issue.fabricate! do |issue|
+ Resource::Issue.fabricate_via_browser_ui! do |issue|
issue.title = issue_title
end
expect(page).to have_content(issue_title)
Page::Project::Issue::Show.perform do |show_page|
- show_page.select_comments_only_filter
- show_page.comment('/confidential')
- show_page.comment('My own comment')
+ show_page.comment('/confidential', filter: :comments_only)
+ show_page.comment('My own comment', filter: :comments_only)
expect(show_page).not_to have_content("made the issue confidential")
expect(show_page).to have_content("My own comment")
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
index 0ff71baed90..6969f123f95 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
@@ -1,74 +1,64 @@
# frozen_string_literal: true
module QA
- # Failure issue: https://gitlab.com/gitlab-org/quality/staging/issues/50
- context 'Create', :quarantine do
- describe 'Merge request creation' do
- it 'user creates a new merge request', :smoke do
+ context 'Create' do
+ describe 'Create a new merge request' do
+ before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
+ Page::Main::Login.perform(&:sign_in_using_credentials)
- current_project = Resource::Project.fabricate! do |project|
- project.name = 'project-with-merge-request'
+ @project = Resource::Project.fabricate_via_api! do |project|
+ project.name = 'project'
end
- merge_request_title = 'This is a merge request'
- merge_request_description = 'Great feature'
+ @merge_request_title = 'One merge request to rule them all'
+ @merge_request_description = '... to find them, to bring them all, and in the darkness bind them'
+ end
- Resource::MergeRequest.fabricate! do |merge_request|
- merge_request.title = merge_request_title
- merge_request.description = merge_request_description
- merge_request.project = current_project
+ it 'creates a basic merge request', :smoke do
+ Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
+ merge_request.project = @project
+ merge_request.title = @merge_request_title
+ merge_request.description = @merge_request_description
end
- expect(page).to have_content(merge_request_title)
- expect(page).to have_content(merge_request_description)
- expect(page).to have_content(/Opened [\w\s]+ ago/)
+ Page::MergeRequest::Show.perform do |merge_request|
+ expect(merge_request).to have_title(@merge_request_title)
+ expect(merge_request).to have_description(@merge_request_description)
+ end
end
- it 'user creates a new merge request with a milestone and label' do
+ it 'creates a merge request with a milestone and label' do
gitlab_account_username = "@#{Runtime::User.username}"
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- current_project = Resource::Project.fabricate! do |project|
- project.name = 'project-with-merge-request-and-milestone'
- end
-
- current_milestone = Resource::ProjectMilestone.fabricate! do |milestone|
- milestone.title = 'unique-milestone'
- milestone.project = current_project
+ milestone = Resource::ProjectMilestone.fabricate_via_api! do |milestone|
+ milestone.project = @project
+ milestone.title = 'milestone'
end
- new_label = Resource::Label.fabricate! do |label|
- label.project = current_project
- label.title = 'qa-mr-test-label'
- label.description = 'Merge Request label'
+ label = Resource::Label.fabricate_via_api! do |label|
+ label.project = @project
+ label.title = 'label'
end
- merge_request_title = 'This is a merge request with a milestone and a label'
- merge_request_description = 'Great feature with milestone'
-
- Resource::MergeRequest.fabricate! do |merge_request|
- merge_request.title = merge_request_title
- merge_request.description = merge_request_description
- merge_request.project = current_project
- merge_request.milestone = current_milestone
+ Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
+ merge_request.title = @merge_request_title
+ merge_request.description = @merge_request_description
+ merge_request.project = @project
+ merge_request.milestone = milestone
merge_request.assignee = 'me'
- merge_request.labels.push(new_label)
+ merge_request.labels.push(label)
end
Page::MergeRequest::Show.perform do |merge_request|
- expect(merge_request).to have_content(merge_request_title)
- expect(merge_request).to have_content(merge_request_description)
- expect(merge_request).to have_content(/Opened [\w\s]+ ago/)
+ expect(merge_request).to have_title(@merge_request_title)
+ expect(merge_request).to have_description(@merge_request_description)
expect(merge_request).to have_assignee(gitlab_account_username)
- expect(merge_request).to have_label(new_label.title)
+ expect(merge_request).to have_label(label.title)
end
Page::Issuable::Sidebar.perform do |sidebar|
- expect(sidebar).to have_milestone(current_milestone.title)
+ expect(sidebar).to have_milestone(milestone.title)
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
index c7db595284e..6ca7af8a3af 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module QA
- # Failure issue: https://gitlab.com/gitlab-org/quality/nightly/issues/94
- context 'Create', :quarantine do
+ context 'Create' do
describe 'Merge request creation from fork' do
it 'user forks a project, submits a merge request and maintainer merges it' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
index 86692623790..a93f2695ec2 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module QA
- # Failure issue: https://gitlab.com/gitlab-org/quality/nightly/issues/93
- context 'Create', :quarantine do
+ context 'Create' do
describe 'Merge request squashing' do
it 'user squashes commits while merging' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
index 2750b171a85..567c6a83ddf 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
@@ -2,8 +2,7 @@
module QA
context 'Create' do
- # Issue: https://gitlab.com/gitlab-org/quality/nightly/issues/97
- describe 'File templates', :quarantine do
+ describe 'File templates' do
include Runtime::Fixtures
def login
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
index 37a784248d4..2b3d9b1711d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module QA
- # Failure issue: https://gitlab.com/gitlab-org/quality/nightly/issues/62
- context 'Create', :quarantine do
+ context 'Create' do
describe 'Create, list, and delete branches via web' do
master_branch = 'master'
second_branch = 'second-branch'
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
index 5bfafdfa041..247cde38e52 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
@@ -1,74 +1,57 @@
# frozen_string_literal: true
module QA
- # Failure issue: https://gitlab.com/gitlab-org/quality/staging/issues/37
- context 'Create', :quarantine do
+ context 'Create', :requires_admin do
describe 'push after setting the file size limit via admin/application_settings' do
- before(:all) do
- push = Resource::Repository::ProjectPush.fabricate! do |p|
- p.file_name = 'README.md'
- p.file_content = '# This is a test project'
- p.commit_message = 'Add README.md'
+ before(:context) do
+ @project = Resource::Project.fabricate_via_api! do |p|
+ p.name = 'project-test-push-limit'
+ p.initialize_with_readme = true
end
- @project = push.project
+ @api_client = Runtime::API::Client.new(:gitlab, personal_access_token: Runtime::Env.admin_personal_access_token)
end
- before do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.perform(&:sign_in_using_credentials)
- end
-
- after(:all) do
+ after(:context) do
# need to set the default value after test
# default value for file size limit is empty
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.perform(&:sign_in_using_credentials)
-
- set_file_size_limit('')
-
- Page::Main::Menu.perform(&:sign_out)
+ set_file_size_limit(nil)
end
it 'push successful when the file size is under the limit' do
set_file_size_limit(5)
- expect(page).to have_content("Application settings saved successfully")
-
push = push_new_file('oversize_file_1.bin', wait_for_push: true)
expect(push.output).not_to have_content 'remote: fatal: pack exceeds maximum allowed size'
end
it 'push fails when the file size is above the limit' do
set_file_size_limit(1)
- expect(page).to have_content("Application settings saved successfully")
-
expect { push_new_file('oversize_file_2.bin', wait_for_push: false) }
.to raise_error(QA::Git::Repository::RepositoryCommandError, /remote: fatal: pack exceeds maximum allowed size/)
end
def set_file_size_limit(limit)
- Page::Main::Menu.perform(&:click_admin_area)
- Page::Admin::Menu.perform(&:go_to_general_settings)
+ request = Runtime::API::Request.new(@api_client, '/application/settings')
+ put request.url, receive_max_input_size: limit
- Page::Admin::Settings::General.perform do |setting|
- setting.expand_account_and_limit do |page|
- page.set_max_file_size(limit)
- page.save_settings
- end
- end
+ expect_status(200)
+ expect(json_body).to match(
+ a_hash_including(receive_max_input_size: limit)
+ )
end
def push_new_file(file_name, wait_for_push: true)
- @project.visit!
-
- Resource::Repository::ProjectPush.fabricate! do |p|
- p.project = @project
+ commit_message = 'Adding a new file'
+ output = Resource::Repository::Push.fabricate! do |p|
+ p.repository_http_uri = @project.repository_http_location.uri
p.file_name = file_name
p.file_content = SecureRandom.random_bytes(2000000)
- p.commit_message = 'Adding a new file'
- p.wait_for_push = wait_for_push
+ p.commit_message = commit_message
p.new_branch = false
end
+ @project.wait_for_push commit_message
+
+ output
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb
index f6f0468e76e..796de44a012 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module QA
- # Failure issue: https://gitlab.com/gitlab-org/quality/staging/issues/49
- context 'Create', :smoke, :quarantine do
+ context 'Create', :smoke do
describe 'Snippet creation' do
it 'User creates a snippet' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
@@ -13,7 +12,7 @@ module QA
Resource::Snippet.fabricate_via_browser_ui! do |snippet|
snippet.title = 'Snippet title'
snippet.description = 'Snippet description'
- snippet.visibility = 'Public'
+ snippet.visibility = 'Private'
snippet.file_name = 'New snippet file name'
snippet.file_content = 'Snippet file text'
end
@@ -21,8 +20,7 @@ module QA
Page::Dashboard::Snippet::Show.perform do |snippet|
expect(snippet).to have_snippet_title('Snippet title')
expect(snippet).to have_snippet_description('Snippet description')
- expect(snippet).to have_embed_type('Embed')
- expect(snippet).to have_visibility_type('Public')
+ expect(snippet).to have_visibility_type('Private')
expect(snippet).to have_file_name('New snippet file name')
expect(snippet).to have_file_content('Snippet file text')
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
index 078d3b2b5b1..c09c65a57a5 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module QA
- # Failure issue: https://gitlab.com/gitlab-org/quality/staging/issues/46
- context 'Create', :quarantine do
+ context 'Create' do
describe 'Web IDE file templates' do
include Runtime::Fixtures
diff --git a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb b/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
index fc4ff364fd4..a04efb94def 100644
--- a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
+++ b/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
@@ -19,7 +19,7 @@ module QA
it 'shows results for the original request and AJAX requests' do
# Issue pages always make AJAX requests
- Resource::Issue.fabricate! do |issue|
+ Resource::Issue.fabricate_via_browser_ui! do |issue|
issue.title = 'Performance bar test'
end
diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb
index a5c86425465..203064b2665 100644
--- a/qa/qa/support/api.rb
+++ b/qa/qa/support/api.rb
@@ -16,11 +16,12 @@ module QA
e.response
end
- def get(url)
+ def get(url, raw_response: false)
RestClient::Request.execute(
method: :get,
url: url,
- verify_ssl: false)
+ verify_ssl: false,
+ raw_response: raw_response)
rescue RestClient::ExceptionWithResponse => e
e.response
end
diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb
index 02ebd96ad49..93d8fa99c0a 100644
--- a/qa/qa/support/page/logging.rb
+++ b/qa/qa/support/page/logging.rb
@@ -125,7 +125,7 @@ module QA
super
end
- def within_element(name)
+ def within_element(name, text: nil)
log("within element :#{name}")
element = super
diff --git a/qa/qa/tools/generate_perf_testdata.rb b/qa/qa/tools/generate_perf_testdata.rb
index de8cfa1aed9..b0477951967 100644
--- a/qa/qa/tools/generate_perf_testdata.rb
+++ b/qa/qa/tools/generate_perf_testdata.rb
@@ -19,26 +19,30 @@ module QA
raise ArgumentError, "Please provide GITLAB_QA_ACCESS_TOKEN" unless ENV['GITLAB_QA_ACCESS_TOKEN']
@api_client = Runtime::API::Client.new(ENV['GITLAB_ADDRESS'], personal_access_token: ENV['GITLAB_QA_ACCESS_TOKEN'])
- @group_name = "gitlab-qa-perf-sandbox-#{SecureRandom.hex(8)}"
- @project_name = "my-test-project-#{SecureRandom.hex(8)}"
+ @group_name = ENV['GROUP_NAME'] || "gitlab-qa-perf-sandbox-#{SecureRandom.hex(8)}"
+ @project_name = ENV['PROJECT_NAME'] || "my-test-project-#{SecureRandom.hex(8)}"
@visibility = "public"
@urls = { host: ENV['GITLAB_ADDRESS'] }
end
- def run
+ def all
STDOUT.puts 'Running...'
group_id = create_group
create_project(group_id)
- create_branch
- add_new_file
+
+ create_many_branches
+ create_many_new_files
+ create_mr_with_many_commits
+
methods_arr = [
- method(:create_issues),
- method(:create_labels),
- method(:create_todos),
- method(:create_merge_requests),
- method(:create_issue_with_500_discussions),
- method(:create_mr_with_large_files)
+ method(:create_many_issues),
+ method(:create_many_labels),
+ method(:create_many_todos),
+ method(:create_many_merge_requests),
+ method(:create_an_issue_with_many_discussions),
+ method(:create_an_mr_with_large_files_and_many_mr_discussions)
]
+
threads_arr = []
methods_arr.each do |m|
@@ -51,103 +55,102 @@ module QA
STDOUT.puts "\nDone"
end
- private
-
def create_group
- group_search_response = post Runtime::API::Request.new(@api_client, "/groups").url, "name=#{@group_name}&path=#{@group_name}&visibility=#{@visibility}"
+ group_search_response = create_a_group_api_req(@group_name, @visibility)
group = JSON.parse(group_search_response.body)
@urls[:group_page] = group["web_url"]
group["id"]
+ STDOUT.puts "Created a group: #{@urls[:group_page]}"
end
def create_project(group_id)
- create_project_response = post Runtime::API::Request.new(@api_client, "/projects").url, "name=#{@project_name}&namespace_id=#{group_id}&visibility=#{@visibility}"
+ create_project_response = create_a_project_api_req(@project_name, group_id, @visibility)
@urls[:project_page] = JSON.parse(create_project_response.body)["web_url"]
+ STDOUT.puts "Created a project: #{@urls[:project_page]}"
end
- def create_issues
+ def create_many_issues
30.times do |i|
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/issues").url, "title=issue#{i}&description=desc#{i}"
+ create_an_issue_api_req("#{@group_name}%2F#{@project_name}", "issue#{i}", "desc#{i}")
end
@urls[:issues_list_page] = @urls[:project_page] + "/issues"
- STDOUT.puts "Created Issues"
+ STDOUT.puts "Created many issues: #{@urls[:issues_list_page]}"
end
- def create_todos
+ def create_many_todos
30.times do |i|
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/issues/#{i + 1}/todo").url, nil
+ create_a_todo_api_req("#{@group_name}%2F#{@project_name}", "#{i + 1}")
end
@urls[:todos_page] = ENV['GITLAB_ADDRESS'] + "/dashboard/todos"
- STDOUT.puts "Created todos"
+ STDOUT.puts "Created many todos: #{@urls[:todos_page]}"
end
- def create_labels
+ def create_many_labels
30.times do |i|
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/labels").url,
- "name=label#{i}&color=#{Faker::Color.hex_color}"
+ create_a_label_api_req("#{@group_name}%2F#{@project_name}", "label#{i}", "#{Faker::Color.hex_color}")
end
@urls[:labels_page] = @urls[:project_page] + "/labels"
- STDOUT.puts "Created labels"
+ STDOUT.puts "Created many labels: #{@urls[:labels_page]}"
end
- def create_merge_requests
+ def create_many_merge_requests
30.times do |i|
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/merge_requests").url, "source_branch=branch#{i}&target_branch=master&title=MR#{i}"
+ create_a_merge_request_api_req("#{@group_name}%2F#{@project_name}", "branch#{i}", "master", "MR#{i}")
end
@urls[:mr_list_page] = @urls[:project_page] + "/merge_requests"
- STDOUT.puts "Created MRs"
+ STDOUT.puts "Created many MRs: #{@urls[:mr_list_page]}"
end
- def add_new_file
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/repository/files/hello.txt").url, "branch=master&commit_message=\"hello\"&content=\"my new content\""
+ def create_many_new_files
+ create_a_new_file_api_req("hello.txt", "master", "#{@group_name}%2F#{@project_name}", "hello", "my new content")
30.times do |i|
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/repository/files/hello#{i}.txt").url, "branch=branch#{i}&commit_message=\"hello\"&content=\"my new content\""
+ create_a_new_file_api_req("hello#{i}.txt", "branch#{i}", "#{@group_name}%2F#{@project_name}", "hello", "my new content")
end
- STDOUT.puts "Added Files"
+
+ @urls[:files_page] = @urls[:project_page] + "/tree/master"
+ STDOUT.puts "Added many new files: #{@urls[:files_page]}"
end
- def create_branch
+ def create_many_branches
30.times do |i|
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/repository/branches").url, "branch=branch#{i}&ref=master"
+ create_a_branch_api_req("branch#{i}", "#{@group_name}%2F#{@project_name}")
end
- STDOUT.puts "Created branches"
+ @urls[:branches_page] = @urls[:project_page] + "/-/branches"
+ STDOUT.puts "Created many branches: #{@urls[:branches_page]}"
end
- def create_issue_with_500_discussions
+ def create_an_issue_with_many_discussions
issue_id = 1
500.times do
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/issues/#{issue_id}/discussions").url, "body=\"Let us discuss\""
+ create_a_discussion_on_issue_api_req("#{@group_name}%2F#{@project_name}", issue_id, "Let us discuss")
end
- labels_list = (0..15).map {|i| "label#{i}"}.join(',')
+ labels_list = (0..15).map { |i| "label#{i}" }.join(',')
# Add description and labels
- put Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/issues/#{issue_id}").url, "description=#{Faker::Lorem.sentences(500).join(" ")}&labels=#{labels_list}"
+ update_an_issue_api_req("#{@group_name}%2F#{@project_name}", issue_id, "#{Faker::Lorem.sentences(500).join(" ")}", labels_list)
@urls[:large_issue] = @urls[:project_page] + "/issues/#{issue_id}"
- STDOUT.puts "Created Issue with 500 Discussions"
+ STDOUT.puts "Created an issue with many discussions: #{@urls[:large_issue]}"
end
- def create_mr_with_large_files
+ def create_an_mr_with_large_files_and_many_mr_discussions
content_arr = []
16.times do |i|
faker_line_arr = Faker::Lorem.sentences(1500)
content = faker_line_arr.join("\n\r")
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/repository/files/hello#{i}.txt").url,
- "branch=master&commit_message=\"Add hello#{i}.txt\"&content=#{content}"
+ create_a_new_file_api_req("hello#{i}.txt", "master", "#{@group_name}%2F#{@project_name}", "Add hello#{i}.txt", content)
content_arr[i] = faker_line_arr
end
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/repository/branches").url,
- "branch=performance&ref=master"
+ create_a_branch_api_req("performance", "#{@group_name}%2F#{@project_name}")
16.times do |i|
missed_line_array = content_arr[i].each_slice(2).map(&:first)
content = missed_line_array.join("\n\rIm new!:D \n\r ")
- put Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/repository/files/hello#{i}.txt").url,
- "branch=performance&commit_message=\"Update hello#{i}.txt\"&content=#{content}"
+
+ update_file_api_req("hello#{i}.txt", "performance", "#{@group_name}%2F#{@project_name}", "Update hello#{i}.txt", content)
end
- create_mr_response = post Runtime::API::Request.new(@api_client, """/projects/#{@group_name}%2F#{@project_name}/merge_requests""").url,
- "source_branch=performance&target_branch=master&title=Large_MR"
+ create_mr_response = create_a_merge_request_api_req("#{@group_name}%2F#{@project_name}", "performance", "master", "Large_MR")
iid = JSON.parse(create_mr_response.body)["iid"]
diff_refs = JSON.parse(create_mr_response.body)["diff_refs"]
@@ -161,8 +164,8 @@ module QA
if should_resolve
discussion_id = JSON.parse(create_diff_note_response.body)["id"]
- put Runtime::API::Request.new(@api_client, """/projects/#{@group_name}%2F#{@project_name}/merge_requests/#{iid}/discussions/#{discussion_id}""").url,
- "resolved=true"
+
+ update_a_discussion_on_issue_api_req("#{@group_name}%2F#{@project_name}", iid, discussion_id, "true")
end
should_resolve ^= true
@@ -171,23 +174,93 @@ module QA
# Add discussions to main tab
100.times do
- post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/merge_requests/#{iid}/discussions").url,
- "body=\"Let us discuss\""
+ create_a_discussion_on_mr_api_req("#{@group_name}%2F#{@project_name}", iid, "Let us discuss")
end
@urls[:large_mr] = JSON.parse(create_mr_response.body)["web_url"]
- STDOUT.puts "Created MR with 500 Discussions and 20 Very Large Files"
+ STDOUT.puts "Created an MR with many discussions and many very large Files: #{@urls[:large_mr]}"
end
def create_diff_note(iid, file_count, line_count, head_sha, start_sha, base_sha, line_type)
post Runtime::API::Request.new(@api_client, "/projects/#{@group_name}%2F#{@project_name}/merge_requests/#{iid}/discussions").url,
- """body=\"Let us discuss\"&
+ "" "body=\"Let us discuss\"&
position[position_type]=text&
position[new_path]=hello#{file_count}.txt&
position[old_path]=hello#{file_count}.txt&
position[#{line_type}]=#{line_count * 100}&
position[head_sha]=#{head_sha}&
position[start_sha]=#{start_sha}&
- position[base_sha]=#{base_sha}"""
+ position[base_sha]=#{base_sha}" ""
+ end
+
+ def create_mr_with_many_commits
+ project_path = "#{@group_name}%2F#{@project_name}"
+ branch_name = "branch_with_many_commits-#{SecureRandom.hex(8)}"
+ file_name = "file_for_many_commits.txt"
+ create_a_branch_api_req(branch_name, project_path)
+ create_a_new_file_api_req(file_name, branch_name, project_path, "Initial commit for new file", "Initial file content")
+ create_mr_response = create_a_merge_request_api_req(project_path, branch_name, "master", "MR with many commits-#{SecureRandom.hex(8)}")
+ @urls[:mr_with_many_commits] = JSON.parse(create_mr_response.body)["web_url"]
+ 100.times do |i|
+ update_file_api_req(file_name, branch_name, project_path, Faker::Lorem.sentences(5).join(" "), Faker::Lorem.sentences(500).join("\n"))
+ end
+ STDOUT.puts "Created an MR with many commits: #{@urls[:mr_with_many_commits]}"
+ end
+
+ private
+
+ # API Requests
+
+ def create_a_discussion_on_issue_api_req(project_path_or_id, issue_id, body)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/issues/#{issue_id}/discussions").url, "body=\"#{body}\""
+ end
+
+ def update_a_discussion_on_issue_api_req(project_path_or_id, mr_iid, discussion_id, resolved_status)
+ put Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/merge_requests/#{mr_iid}/discussions/#{discussion_id}").url, "resolved=#{resolved_status}"
+ end
+
+ def create_a_discussion_on_mr_api_req(project_path_or_id, mr_iid, body)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/merge_requests/#{mr_iid}/discussions").url,
+ "body=\"#{body}\""
+ end
+
+ def create_a_label_api_req(project_path_or_id, name, color)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/labels").url, "name=#{name}&color=#{color}"
+ end
+
+ def create_a_todo_api_req(project_path_or_id, issue_id)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/issues/#{issue_id}/todo").url, nil
+ end
+
+ def create_an_issue_api_req(project_path_or_id, title, description)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/issues").url, "title=#{title}&description=#{description}"
+ end
+
+ def update_an_issue_api_req(project_path_or_id, issue_id, description, labels_list)
+ put Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/issues/#{issue_id}").url, "description=#{description}&labels=#{labels_list}"
+ end
+
+ def create_a_project_api_req(project_name, group_id, visibility)
+ post Runtime::API::Request.new(@api_client, "/projects").url, "name=#{project_name}&namespace_id=#{group_id}&visibility=#{visibility}"
+ end
+
+ def create_a_group_api_req(group_name, visibility)
+ post Runtime::API::Request.new(@api_client, "/groups").url, "name=#{group_name}&path=#{group_name}&visibility=#{visibility}"
+ end
+
+ def create_a_branch_api_req(branch_name, project_path_or_id)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/repository/branches").url, "branch=#{branch_name}&ref=master"
+ end
+
+ def create_a_new_file_api_req(file_path, branch_name, project_path_or_id, commit_message, content)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/repository/files/#{file_path}").url, "branch=#{branch_name}&commit_message=\"#{commit_message}\"&content=\"#{content}\""
+ end
+
+ def create_a_merge_request_api_req(project_path_or_id, source_branch, target_branch, mr_title)
+ post Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/merge_requests").url, "source_branch=#{source_branch}&target_branch=#{target_branch}&title=#{mr_title}"
+ end
+
+ def update_file_api_req(file_path, branch_name, project_path_or_id, commit_message, content)
+ put Runtime::API::Request.new(@api_client, "/projects/#{project_path_or_id}/repository/files/#{file_path}").url, "branch=#{branch_name}&commit_message=\"#{commit_message}\"&content=\"#{content}\""
end
end
end
diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb
index 092c6a17c9c..0f1ed039149 100644
--- a/qa/spec/page/logging_spec.rb
+++ b/qa/spec/page/logging_spec.rb
@@ -135,9 +135,9 @@ describe QA::Support::Page::Logging do
end
it 'logs within_element' do
- expect { subject.within_element(:element) }
+ expect { subject.within_element(:element, text: nil) }
.to output(/within element :element/).to_stdout_from_any_process
- expect { subject.within_element(:element) }
+ expect { subject.within_element(:element, text: nil) }
.to output(/end within element :element/).to_stdout_from_any_process
end
diff --git a/qa/spec/runtime/api/client_spec.rb b/qa/spec/runtime/api/client_spec.rb
index cf19b52700b..6f7020d6595 100644
--- a/qa/spec/runtime/api/client_spec.rb
+++ b/qa/spec/runtime/api/client_spec.rb
@@ -16,26 +16,56 @@ describe QA::Runtime::API::Client do
end
describe '#personal_access_token' do
- context 'when QA::Runtime::Env.personal_access_token is present' do
+ context 'when user is nil and QA::Runtime::Env.personal_access_token is present' do
before do
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token')
end
it 'returns specified token from env' do
- expect(described_class.new.personal_access_token).to eq 'a_token'
+ expect(subject.personal_access_token).to eq 'a_token'
end
end
- context 'when QA::Runtime::Env.personal_access_token is nil' do
+ context 'when user is present and QA::Runtime::Env.personal_access_token is nil' do
before do
allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil)
end
it 'returns a created token' do
+ subject { described_class.new(user: { username: 'foo' }) }
+
expect(subject).to receive(:create_personal_access_token).and_return('created_token')
expect(subject.personal_access_token).to eq 'created_token'
end
end
+
+ context 'when user is nil and QA::Runtime::Env.personal_access_token is nil' do
+ before do
+ allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil)
+ end
+
+ it 'returns a created token' do
+ client = described_class.new
+
+ expect(client).to receive(:create_personal_access_token).and_return('created_token')
+
+ expect(client.personal_access_token).to eq 'created_token'
+ end
+ end
+
+ context 'when user is present and QA::Runtime::Env.personal_access_token is present' do
+ before do
+ allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token')
+ end
+
+ it 'returns a created token' do
+ client = described_class.new(user: { username: 'foo' })
+
+ expect(client).to receive(:create_personal_access_token).and_return('created_token')
+
+ expect(client.personal_access_token).to eq 'created_token'
+ end
+ end
end
end
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index 2560695ef2e..caf96a213e1 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -227,6 +227,12 @@ describe QA::Runtime::Env do
env_key: 'QA_CAN_TEST_GIT_PROTOCOL_V2',
default: true
+ it_behaves_like 'boolean method with parameter',
+ method: :can_test?,
+ param: :admin,
+ env_key: 'QA_CAN_TEST_ADMIN_FEATURES',
+ default: true
+
it 'raises ArgumentError if feature is unknown' do
expect { described_class.can_test? :foo }.to raise_error(ArgumentError, 'Unknown feature "foo"')
end
diff --git a/qa/spec/specs/runner_spec.rb b/qa/spec/specs/runner_spec.rb
index 5c86c102105..f94145d148e 100644
--- a/qa/spec/specs/runner_spec.rb
+++ b/qa/spec/specs/runner_spec.rb
@@ -1,16 +1,22 @@
# frozen_string_literal: true
+require 'active_support/core_ext/hash'
+
describe QA::Specs::Runner do
+ shared_examples 'excludes orchestrated' do
+ it 'excludes the orchestrated tag and includes default args' do
+ expect_rspec_runner_arguments(['--tag', '~orchestrated', *described_class::DEFAULT_TEST_PATH_ARGS])
+
+ subject.perform
+ end
+ end
+
context '#perform' do
before do
allow(QA::Runtime::Browser).to receive(:configure!)
end
- it 'excludes the orchestrated tag by default' do
- expect_rspec_runner_arguments(['--tag', '~orchestrated', *described_class::DEFAULT_TEST_PATH_ARGS])
-
- subject.perform
- end
+ it_behaves_like 'excludes orchestrated'
context 'when tty is set' do
subject { described_class.new.tap { |runner| runner.tty = true } }
@@ -67,8 +73,6 @@ describe QA::Specs::Runner do
allow(QA::Runtime::Env).to receive(:signup_disabled?).and_return(true)
end
- subject { described_class.new }
-
it 'includes default args and excludes the skip_signup_disabled tag' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~skip_signup_disabled', *described_class::DEFAULT_TEST_PATH_ARGS])
@@ -76,18 +80,54 @@ describe QA::Specs::Runner do
end
end
- context 'when git protocol v2 is not supported' do
- before do
- allow(QA::Runtime::Env).to receive(:can_test?).with(:git_protocol_v2).and_return(false)
+ context 'testable features' do
+ shared_examples 'one supported feature' do |feature|
+ before do
+ QA::Runtime::Env.supported_features.each do |tag, _|
+ allow(QA::Runtime::Env).to receive(:can_test?).with(tag).and_return(false)
+ end
+
+ allow(QA::Runtime::Env).to receive(:can_test?).with(feature).and_return(true) unless feature.nil?
+ end
+
+ it 'includes default args and excludes all unsupported tags' do
+ expect_rspec_runner_arguments(['--tag', '~orchestrated', *excluded_feature_tags_except(feature), *described_class::DEFAULT_TEST_PATH_ARGS])
+
+ subject.perform
+ end
end
- subject { described_class.new }
+ context 'when only git protocol 2 is supported' do
+ it_behaves_like 'one supported feature', :git_protocol_v2
+ end
- it 'includes default args and excludes the requires_git_protocol_v2 tag' do
- expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~requires_git_protocol_v2', *described_class::DEFAULT_TEST_PATH_ARGS])
+ context 'when only admin features are supported' do
+ it_behaves_like 'one supported feature', :admin
+ end
- subject.perform
+ context 'when no features are supported' do
+ it_behaves_like 'one supported feature', nil
end
+
+ context 'when all features are supported' do
+ before do
+ QA::Runtime::Env.supported_features.each do |tag, _|
+ allow(QA::Runtime::Env).to receive(:can_test?).with(tag).and_return(true)
+ end
+ end
+
+ it_behaves_like 'excludes orchestrated'
+ end
+
+ context 'when features are not specified' do
+ it_behaves_like 'excludes orchestrated'
+ end
+ end
+
+ def excluded_feature_tags_except(tag)
+ QA::Runtime::Env.supported_features.except(tag).map do |tag, _|
+ ['--tag', "~requires_#{tag}"]
+ end.flatten
end
def expect_rspec_runner_arguments(arguments)