diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-20 12:07:57 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-20 12:07:57 +0300 |
commit | 7881eb30eaa8b01dbcfe87faa09927c75c7d6e45 (patch) | |
tree | 298bc8d2c62b2f2c29cb8ecbcf3de3eaaa6466d9 /qa | |
parent | 64b66e0cb6d1bfd27abf24e06653f00bddb60597 (diff) |
Add latest changes from gitlab-org/gitlab@12-6-stable-ee
Diffstat (limited to 'qa')
94 files changed, 710 insertions, 439 deletions
diff --git a/qa/.gitignore b/qa/.gitignore index b0ae074ac07..7bc4effd8a8 100644 --- a/qa/.gitignore +++ b/qa/.gitignore @@ -1,3 +1,4 @@ tmp/ .ruby-version +.ruby-gemset urls.yml diff --git a/qa/Gemfile b/qa/Gemfile index 5266fc57b0a..3575ecf13e9 100644 --- a/qa/Gemfile +++ b/qa/Gemfile @@ -2,8 +2,8 @@ source 'https://rubygems.org' gem 'gitlab-qa' gem 'activesupport', '5.2.3' # This should stay in sync with the root's Gemfile -gem 'capybara', '~> 2.16.1' -gem 'capybara-screenshot', '~> 1.0.18' +gem 'capybara', '~> 3.29.0' +gem 'capybara-screenshot', '~> 1.0.23' gem 'rake', '~> 12.3.0' gem 'rspec', '~> 3.7' gem 'selenium-webdriver', '~> 3.12' diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock index 84eab990c95..25c7703ef52 100644 --- a/qa/Gemfile.lock +++ b/qa/Gemfile.lock @@ -6,8 +6,8 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.5.2) - public_suffix (>= 2.0.2, < 4.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) airborne (0.2.13) activesupport rack @@ -15,18 +15,18 @@ GEM rest-client (>= 1.7.3, < 3.0) rspec (~> 3.1) byebug (9.1.0) - capybara (2.16.1) + capybara (3.29.0) addressable mini_mime (>= 0.1.3) - nokogiri (>= 1.3.3) - rack (>= 1.0.0) - rack-test (>= 0.5.4) - xpath (~> 2.0) - capybara-screenshot (1.0.18) - capybara (>= 1.0, < 3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (~> 1.5) + xpath (~> 3.2) + capybara-screenshot (1.0.23) + capybara (>= 1.0, < 4) launchy - childprocess (0.9.0) - ffi (~> 1.0, >= 1.0.11) + childprocess (3.0.0) coderay (1.1.2) concurrent-ruby (1.1.5) debase (0.2.4.1) @@ -37,7 +37,6 @@ GEM unf (>= 0.0.5, < 1.0.0) faker (1.9.3) i18n (>= 0.7) - ffi (1.9.25) gitlab-qa (4.0.0) http-cookie (1.0.3) domain_name (~> 0.5) @@ -51,7 +50,7 @@ GEM mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) - mini_mime (1.0.0) + mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.11.3) netrc (0.11.0) @@ -66,11 +65,12 @@ GEM pry-byebug (3.5.1) byebug (~> 9.1) pry (~> 0.10) - public_suffix (3.0.1) - rack (2.0.6) - rack-test (0.8.2) + public_suffix (4.0.1) + rack (2.0.7) + rack-test (0.8.3) rack (>= 1.0, < 3) - rake (12.3.3) + rake (12.3.0) + regexp_parser (1.6.0) rest-client (2.0.2) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) @@ -95,17 +95,17 @@ GEM ruby-debug-ide (0.7.0) rake (>= 0.8.1) rubyzip (1.2.2) - selenium-webdriver (3.141.0) - childprocess (~> 0.5) - rubyzip (~> 1.2, >= 1.2.2) + selenium-webdriver (3.142.6) + childprocess (>= 0.5, < 4.0) + rubyzip (>= 1.2.2) thread_safe (0.3.6) tzinfo (1.2.5) thread_safe (~> 0.1) unf (0.1.4) unf_ext unf_ext (0.0.7.4) - xpath (2.1.0) - nokogiri (~> 1.3) + xpath (3.2.0) + nokogiri (~> 1.8) PLATFORMS ruby @@ -113,8 +113,8 @@ PLATFORMS DEPENDENCIES activesupport (= 5.2.3) airborne (~> 0.2.13) - capybara (~> 2.16.1) - capybara-screenshot (~> 1.0.18) + capybara (~> 3.29.0) + capybara-screenshot (~> 1.0.23) debase (~> 0.2.4.1) faker (~> 1.6, >= 1.6.6) gitlab-qa @@ -15,6 +15,7 @@ module QA # module Flow autoload :Login, 'qa/flow/login' + autoload :Project, 'qa/flow/project' end ## @@ -33,6 +34,9 @@ module QA autoload :Fixtures, 'qa/runtime/fixtures' autoload :Logger, 'qa/runtime/logger' autoload :GPG, 'qa/runtime/gpg' + autoload :MailHog, 'qa/runtime/mail_hog' + autoload :IPAddress, 'qa/runtime/ip_address' + autoload :Search, 'qa/runtime/search' module API autoload :Client, 'qa/runtime/api/client' @@ -130,6 +134,7 @@ module QA autoload :Kubernetes, 'qa/scenario/test/integration/kubernetes' autoload :Mattermost, 'qa/scenario/test/integration/mattermost' autoload :ObjectStorage, 'qa/scenario/test/integration/object_storage' + autoload :SMTP, 'qa/scenario/test/integration/smtp' end module Sanity @@ -331,6 +336,7 @@ module QA module Admin autoload :Menu, 'qa/page/admin/menu' + autoload :NewSession, 'qa/page/admin/new_session' module Settings autoload :Repository, 'qa/page/admin/settings/repository' @@ -421,6 +427,7 @@ module QA autoload :Maven, 'qa/service/docker_run/maven' autoload :NodeJs, 'qa/service/docker_run/node_js' autoload :GitlabRunner, 'qa/service/docker_run/gitlab_runner' + autoload :MailHog, 'qa/service/docker_run/mail_hog' end end diff --git a/qa/qa/flow/login.rb b/qa/qa/flow/login.rb index d84dfaa9377..5505fabd4ae 100644 --- a/qa/qa/flow/login.rb +++ b/qa/qa/flow/login.rb @@ -5,33 +5,33 @@ module QA module Login module_function - def while_signed_in(as: nil) + def while_signed_in(as: nil, address: :gitlab) Page::Main::Menu.perform(&:sign_out_if_signed_in) - sign_in(as: as) + sign_in(as: as, address: address) yield Page::Main::Menu.perform(&:sign_out) end - def while_signed_in_as_admin - while_signed_in(as: Runtime::User.admin) do + def while_signed_in_as_admin(address: :gitlab) + while_signed_in(as: Runtime::User.admin, address: address) do yield end end - def sign_in(as: nil) - Runtime::Browser.visit(:gitlab, Page::Main::Login) + def sign_in(as: nil, address: :gitlab) + Runtime::Browser.visit(address, Page::Main::Login) Page::Main::Login.perform { |login| login.sign_in_using_credentials(user: as) } end - def sign_in_as_admin - sign_in(as: Runtime::User.admin) + def sign_in_as_admin(address: :gitlab) + sign_in(as: Runtime::User.admin, address: address) end - def sign_in_unless_signed_in(as: nil) - sign_in(as: as) unless Page::Main::Menu.perform(&:signed_in?) + def sign_in_unless_signed_in(as: nil, address: :gitlab) + sign_in(as: as, address: address) unless Page::Main::Menu.perform(&:signed_in?) end end end diff --git a/qa/qa/flow/project.rb b/qa/qa/flow/project.rb new file mode 100644 index 00000000000..72b9357a604 --- /dev/null +++ b/qa/qa/flow/project.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module QA + module Flow + module Project + module_function + + def add_member(project:, username:) + project.visit! + + Page::Project::Menu.perform(&:go_to_members_settings) + + Page::Project::Settings::Members.perform do |member_settings| + member_settings.add_member(username) + end + end + end + end +end diff --git a/qa/qa/page/admin/new_session.rb b/qa/qa/page/admin/new_session.rb new file mode 100644 index 00000000000..3d46bb7f186 --- /dev/null +++ b/qa/qa/page/admin/new_session.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module QA + module Page + module Admin + class NewSession < Page::Base + view 'app/views/admin/sessions/_new_base.html.haml' do + element :enter_admin_mode_button + element :password_field + end + + def set_password(password) + fill_element :password_field, password + end + + def click_enter_admin_mode + click_element :enter_admin_mode_button + end + end + end + end +end diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index ed4d33dc7a3..dcba4fc8544 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -81,16 +81,24 @@ module QA find_element(name, class: 'active') end - def all_elements(name) - all(element_selector_css(name)) + def all_elements(name, **kwargs) + all(element_selector_css(name), **kwargs) end def check_element(name) - find_element(name).set(true) + retry_until(sleep_interval: 1) do + find_element(name).set(true) + + find_element(name).checked? + end end def uncheck_element(name) - find_element(name).set(false) + retry_until(sleep_interval: 1) do + find_element(name).set(false) + + !find_element(name).checked? + end end # replace with (..., page = self.class) @@ -125,16 +133,23 @@ module QA has_no_css?(element_selector_css(name, kwargs), wait: wait, text: text) end - def has_text?(text) - page.has_text? text + def has_text?(text, wait: Capybara.default_max_wait_time) + page.has_text?(text, wait: wait) end def has_no_text?(text) page.has_no_text? text end + def has_normalized_ws_text?(text, wait: Capybara.default_max_wait_time) + page.has_text?(text.gsub(/\s+/, " "), wait: wait) + end + def finished_loading? - has_no_css?('.fa-spinner', wait: Capybara.default_max_wait_time) + # The number of selectors should be able to be reduced after + # migration to the new spinner is complete. + # https://gitlab.com/groups/gitlab-org/-/epics/956 + has_no_css?('.gl-spinner, .fa-spinner, .spinner', wait: Capybara.default_max_wait_time) end def finished_loading_block? @@ -191,12 +206,7 @@ module QA end def within_element_by_index(name, index) - # Finding all elements can be flaky if the elements don't all load - # immediately. So we wait for any to appear before trying to find a - # specific one. - has_element?(name) - - page.within all_elements(name)[index] do + page.within all_elements(name, minimum: index + 1)[index] do yield end end diff --git a/qa/qa/page/component/issuable/common.rb b/qa/qa/page/component/issuable/common.rb index cfd8ac1e7c8..9ecc8f73bdb 100644 --- a/qa/qa/page/component/issuable/common.rb +++ b/qa/qa/page/component/issuable/common.rb @@ -8,6 +8,7 @@ module QA def self.included(base) base.view 'app/assets/javascripts/issue_show/components/title.vue' do element :edit_button + element :title, required: true end base.view 'app/assets/javascripts/issue_show/components/fields/title.vue' do diff --git a/qa/qa/page/component/select2.rb b/qa/qa/page/component/select2.rb index 8fe6a4a75b3..1dd718a1d88 100644 --- a/qa/qa/page/component/select2.rb +++ b/qa/qa/page/component/select2.rb @@ -31,7 +31,7 @@ module QA end def wait_for_search_to_complete - has_css?('.select2-active') + has_css?('.select2-active', wait: 1) has_no_css?('.select2-active', wait: 30) end end diff --git a/qa/qa/page/dashboard/snippet/show.rb b/qa/qa/page/dashboard/snippet/show.rb index a75ea63eca7..88d6ef02d22 100644 --- a/qa/qa/page/dashboard/snippet/show.rb +++ b/qa/qa/page/dashboard/snippet/show.rb @@ -6,8 +6,8 @@ module QA module Snippet class Show < Page::Base view 'app/views/shared/snippets/_header.html.haml' do - element :snippet_title - element :snippet_description + element :snippet_title, required: true + element :snippet_description, required: true element :embed_type element :snippet_box end @@ -21,15 +21,11 @@ module QA end def has_snippet_title?(snippet_title) - within_element(:snippet_title) do - has_text?(snippet_title) - end + has_element? :snippet_title, text: snippet_title end def has_snippet_description?(snippet_description) - within_element(:snippet_description) do - has_text?(snippet_description) - end + has_element? :snippet_description, text: snippet_description end def has_embed_type?(embed_type) diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb index 6353895ffd4..2b3b872aff4 100644 --- a/qa/qa/page/group/menu.rb +++ b/qa/qa/page/group/menu.rb @@ -10,6 +10,7 @@ module QA element :group_settings_item element :group_members_item element :general_settings_link + element :contribution_analytics_link end def click_group_members_item @@ -18,6 +19,12 @@ module QA end end + def click_group_analytics_item + within_sidebar do + click_element(:contribution_analytics_link) + end + end + def click_group_general_settings_item hover_element(:group_settings_item) do within_submenu(:group_sidebar_submenu) do diff --git a/qa/qa/page/issuable/sidebar.rb b/qa/qa/page/issuable/sidebar.rb index 9bb1c702576..af5eee35a2d 100644 --- a/qa/qa/page/issuable/sidebar.rb +++ b/qa/qa/page/issuable/sidebar.rb @@ -5,19 +5,20 @@ module QA module Issuable class Sidebar < Page::Base view 'app/views/shared/issuable/_sidebar.html.haml' do - element :labels_block, ".issuable-show-labels" # rubocop:disable QA/ElementWithPattern - element :milestones_block, '.block.milestone' # rubocop:disable QA/ElementWithPattern + element :labels_block + element :milestone_block + element :milestone_link end def has_label?(label) - page.within('.issuable-show-labels') do - !!find('span', text: label) + within_element(:labels_block) do + has_element?(:label, label_name: label) end end - def has_milestone?(milestone) - page.within('.block.milestone') do - !!find("[href*='/milestones/']", text: milestone) + def has_milestone?(milestone_title) + within_element(:milestone_block) do + has_element?(:milestone_link, title: milestone_title) end end end diff --git a/qa/qa/page/layout/performance_bar.rb b/qa/qa/page/layout/performance_bar.rb index 0cfef6a5705..79e4d3edce0 100644 --- a/qa/qa/page/layout/performance_bar.rb +++ b/qa/qa/page/layout/performance_bar.rb @@ -22,7 +22,7 @@ module QA def has_detailed_metrics? all_elements(:performance_bar_detailed_metric).all? do |metric| - metric.has_text?(%r{\d+ms / \d+}) + metric.has_text?(%r{\d+}) end end diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb index 6e266e26d78..cb3421f93c2 100644 --- a/qa/qa/page/main/login.rb +++ b/qa/qa/page/main/login.rb @@ -42,6 +42,10 @@ module QA element :login_page, required: true end + def can_sign_in? + has_element?(:sign_in_button) + end + def sign_in_using_credentials(user: nil, skip_page_validation: false) # Don't try to log-in if we're already logged-in return if Page::Main::Menu.perform(&:signed_in?) diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb index 49c48568e68..5f4b3946e6a 100644 --- a/qa/qa/page/main/menu.rb +++ b/qa/qa/page/main/menu.rb @@ -60,8 +60,15 @@ module QA end end - def click_admin_area - within_top_menu { click_element :admin_area_link } + def go_to_admin_area + click_admin_area + + if has_text?('Enter Admin Mode', wait: 1.0) + Admin::NewSession.perform do |new_session| + new_session.set_password(Runtime::User.admin_password) + new_session.click_enter_admin_mode + end + end end def signed_in? @@ -125,6 +132,10 @@ module QA end end end + + def click_admin_area + within_top_menu { click_element :admin_area_link } + end end end end diff --git a/qa/qa/page/mattermost/main.rb b/qa/qa/page/mattermost/main.rb index e531ace8529..eea5c4b527e 100644 --- a/qa/qa/page/mattermost/main.rb +++ b/qa/qa/page/mattermost/main.rb @@ -4,11 +4,6 @@ module QA module Page module Mattermost class Main < Page::Base - ## - # TODO, define all selectors required by this page object - # - # See gitlab-org/gitlab-qa#154 - # view 'app/views/projects/mattermosts/new.html.haml' def initialize diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index 14b8c420b16..c3645a6a755 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -26,7 +26,7 @@ module QA end view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue' do - element :merged_status, 'The changes were merged into' # rubocop:disable QA/ElementWithPattern + element :merged_status_content end view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue' do @@ -60,18 +60,35 @@ module QA element :edit_button end + def add_comment_to_diff(text) + wait(interval: 5) do + has_text?("No newline at end of file") + end + all_elements(:new_diff_line).first.hover + click_element :diff_comment + fill_element :reply_input, text + end + def click_discussions_tab click_element :notes_tab + + finished_loading? end def click_diffs_tab click_element :diffs_tab + + finished_loading? end def click_pipeline_link click_element :pipeline_link end + def edit! + click_element :edit_button + end + def fast_forward_possible? has_no_text?('Fast-forward merge is not possible') end @@ -82,39 +99,6 @@ module QA has_element?(:merge_button) end - def has_merge_options? - has_element?(:merge_moment_dropdown) - end - - def merge_immediately - if has_merge_options? - click_element :merge_moment_dropdown - click_element :merge_immediately_option - else - click_element :merge_button - end - end - - def rebase! - # The rebase button is disabled on load - wait do - has_element?(:mr_rebase_button) - end - - # The rebase button is enabled via JS - wait(reload: false) do - !find_element(:mr_rebase_button).disabled? - end - - click_element :mr_rebase_button - - success = wait do - has_text?('Fast-forward merge without a merge commit') - end - - raise "Rebase did not appear to be successful" unless success - end - def has_assignee?(username) page.within(element_selector_css(:assignee_block)) do has_text?(username) @@ -122,9 +106,8 @@ module QA end def has_label?(label) - page.within(element_selector_css(:labels_block)) do - element = find('span', text: label) - !element.nil? + within_element(:labels_block) do + !!has_element?(:label, label_name: label) end end @@ -141,20 +124,6 @@ module QA has_element?(:description, text: description) end - def try_to_merge! - merge_immediately if ready_to_merge? - end - - def merge! - try_to_merge! - - success = wait do - has_text?('The changes were merged into') - end - - raise "Merge did not appear to be successful" unless success - end - def mark_to_squash # The squash checkbox is disabled on load wait do @@ -169,17 +138,14 @@ module QA click_element :squash_checkbox end - def add_comment_to_diff(text) - wait(interval: 5) do - has_text?("No newline at end of file") - end - all_elements(:new_diff_line).first.hover - click_element :diff_comment - fill_element :reply_input, text + def merge! + click_element :merge_button if ready_to_merge? + + raise "Merge did not appear to be successful" unless merged? end - def edit! - click_element :edit_button + def merged? + has_element?(:merged_status_content, text: 'The changes were merged into', wait: 30) end def ready_to_merge? @@ -194,6 +160,30 @@ module QA end end + def rebase! + # The rebase button is disabled on load + wait do + has_element?(:mr_rebase_button) + end + + # The rebase button is enabled via JS + wait(reload: false) do + !find_element(:mr_rebase_button).disabled? + end + + click_element :mr_rebase_button + + success = wait do + has_text?('Fast-forward merge without a merge commit') + end + + raise "Rebase did not appear to be successful" unless success + end + + def try_to_merge! + click_element :merge_button if ready_to_merge? + end + def view_email_patches click_element :dropdown_toggle visit_link_in_element(:download_email_patches) diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb index 6ec80b7c9cc..1ef711d459e 100644 --- a/qa/qa/page/project/issue/show.rb +++ b/qa/qa/page/project/issue/show.rb @@ -26,11 +26,6 @@ module QA element :avatar_image end - view 'app/assets/javascripts/sidebar/components/assignees/assignee_title.vue' do - element :assignee_edit_link - element :assignee_title - end - view 'app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue' do element :more_assignees_link end @@ -44,6 +39,7 @@ module QA end view 'app/views/shared/issuable/_close_reopen_button.html.haml' do + element :close_issue_button element :reopen_issue_button end @@ -60,16 +56,6 @@ module QA element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern end - def assign(user) - click_element(:assignee_edit_link) - select_user(user.username) - click_body - end - - def assignee_title - find_element(:assignee_title) - end - def avatar_image_count wait_assignees_block_finish_loading do all_elements(:avatar_image).count @@ -84,6 +70,10 @@ module QA click_element(:remove_related_issue_button) end + def click_close_issue_button + click_element :close_issue_button + end + # Adds a comment to an issue # attachment option should be an absolute path def comment(text, attachment: nil, filter: :all_activities) @@ -157,25 +147,12 @@ module QA def select_filter_with_text(text) retry_on_exception do - click_body + click_element(:title) click_element :discussion_filter find_element(:filter_options, text: text).click end end - def select_user(username) - find("#{element_selector_css(:assignee_block)} input").set(username) - - dropdown_menu_user_link_selector = '.dropdown-menu-user-link' - at_username = "@#{username}" - ten_seconds = 10 - - wait(reload: false, max: ten_seconds, interval: 1) do - has_css?(dropdown_menu_user_link_selector, wait: ten_seconds, text: at_username) - end - find(dropdown_menu_user_link_selector, text: at_username).click - end - def wait_assignees_block_finish_loading within_element(:assignee_block) do wait(reload: false, max: 10, interval: 1) do diff --git a/qa/qa/page/project/job/show.rb b/qa/qa/page/project/job/show.rb index cf847710024..a1a5b3c296e 100644 --- a/qa/qa/page/project/job/show.rb +++ b/qa/qa/page/project/job/show.rb @@ -27,7 +27,7 @@ module QA::Page wait(reload: false, max: wait, interval: 1) do result = find_element(:build_trace).text - !result.empty? + result.include?('Job') end result diff --git a/qa/qa/page/project/pipeline/index.rb b/qa/qa/page/project/pipeline/index.rb index b52f3e99a36..269d4dfc411 100644 --- a/qa/qa/page/project/pipeline/index.rb +++ b/qa/qa/page/project/pipeline/index.rb @@ -14,11 +14,7 @@ module QA::Page def click_on_latest_pipeline css = '.js-pipeline-url-link' - link = wait(reload: false) do - first(css) - end - - link.click + first(css, wait: 60).click end def wait_for_latest_pipeline_success diff --git a/qa/qa/page/project/settings/advanced.rb b/qa/qa/page/project/settings/advanced.rb index 3a5067a9541..c95c47fa560 100644 --- a/qa/qa/page/project/settings/advanced.rb +++ b/qa/qa/page/project/settings/advanced.rb @@ -12,6 +12,9 @@ module QA element :project_path_field element :change_path_button element :transfer_button + end + + view 'app/views/projects/settings/_archive.html.haml' do element :archive_project_link element :unarchive_project_link end diff --git a/qa/qa/page/project/settings/deploy_keys.rb b/qa/qa/page/project/settings/deploy_keys.rb index b8d961274a9..602bfc64710 100644 --- a/qa/qa/page/project/settings/deploy_keys.rb +++ b/qa/qa/page/project/settings/deploy_keys.rb @@ -12,7 +12,7 @@ module QA view 'app/assets/javascripts/deploy_keys/components/app.vue' do element :deploy_keys_section, /class=".*deploy\-keys.*"/ # rubocop:disable QA/ElementWithPattern - element :project_deploy_keys, 'class="qa-project-deploy-keys"' # rubocop:disable QA/ElementWithPattern + element :project_deploy_keys end view 'app/assets/javascripts/deploy_keys/components/key.vue' do diff --git a/qa/qa/page/search/results.rb b/qa/qa/page/search/results.rb index b9b18abf660..2f99d8da784 100644 --- a/qa/qa/page/search/results.rb +++ b/qa/qa/page/search/results.rb @@ -5,6 +5,7 @@ module QA::Page class Results < QA::Page::Base view 'app/views/search/_category.html.haml' do element :code_tab + element :projects_tab end view 'app/views/search/results/_blob_data.html.haml' do @@ -13,21 +14,33 @@ module QA::Page element :file_text_content end + view 'app/views/shared/projects/_project.html.haml' do + element :project + end + def switch_to_code click_element(:code_tab) end + def switch_to_projects + click_element(:projects_tab) + end + def has_file_in_project?(file_name, project_name) - has_element? :result_item_content, text: "#{project_name}: #{file_name}" + has_element?(:result_item_content, text: "#{project_name}: #{file_name}") end def has_file_with_content?(file_name, file_text) - within_element_by_index :result_item_content, 0 do - false unless has_element? :file_title_content, text: file_name + within_element_by_index(:result_item_content, 0) do + false unless has_element?(:file_title_content, text: file_name) - has_element? :file_text_content, text: file_text + has_element?(:file_text_content, text: file_text) end end + + def has_project?(project_name) + has_element?(:project, project_name: project_name) + end end end end diff --git a/qa/qa/page/settings/common.rb b/qa/qa/page/settings/common.rb index 2d7b41c76e1..bd1070158f0 100644 --- a/qa/qa/page/settings/common.rb +++ b/qa/qa/page/settings/common.rb @@ -6,7 +6,7 @@ module QA module Common # Click the Expand button present in the specified section # - # @param [Symbol] and `element` name defined in a `view` block + # @param [Symbol] element_name `element` name defined in a `view` block def expand_section(element_name) within_element(element_name) do # Because it is possible to click the button before the JS toggle code is bound @@ -14,6 +14,7 @@ module QA click_button 'Expand' unless has_css?('button', text: 'Collapse', wait: 1) has_content?('Collapse') + finished_loading? end yield if block_given? diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb index e4f708dc251..e6057433b55 100644 --- a/qa/qa/resource/api_fabricator.rb +++ b/qa/qa/resource/api_fabricator.rb @@ -19,8 +19,8 @@ module QA def api_support? respond_to?(:api_get_path) && - respond_to?(:api_post_path) && - respond_to?(:api_post_body) + (respond_to?(:api_post_path) && respond_to?(:api_post_body)) || + (respond_to?(:api_put_path) && respond_to?(:api_put_body)) end def fabricate_via_api! @@ -84,11 +84,23 @@ module QA process_api_response(parse_body(response)) end + def api_put + response = put( + Runtime::API::Request.new(api_client, api_put_path).url, + api_put_body) + + unless response.code == HTTP_STATUS_OK + raise ResourceFabricationFailedError, "Updating #{self.class.name} using the API failed (#{response.code}) with `#{response}`." + end + + process_api_response(parse_body(response)) + end + def api_delete url = Runtime::API::Request.new(api_client, api_delete_path).url response = delete(url) - unless response.code == HTTP_STATUS_NO_CONTENT + unless [HTTP_STATUS_NO_CONTENT, HTTP_STATUS_ACCEPTED].include? response.code raise ResourceNotDeletedError, "Resource at #{url} could not be deleted (#{response.code}): `#{response}`." end diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb index ae20ca1a98e..3bb62703290 100644 --- a/qa/qa/resource/base.rb +++ b/qa/qa/resource/base.rb @@ -64,7 +64,7 @@ module QA end def visit! - Runtime::Logger.debug(%Q[Visiting #{self.class.name} at "#{web_url}"]) if Runtime::Env.debug? + Runtime::Logger.debug(%Q[Visiting #{self.class.name} at "#{web_url}"]) Support::Retrier.retry_until do visit(web_url) diff --git a/qa/qa/resource/deploy_token.rb b/qa/qa/resource/deploy_token.rb index f0f0da27412..f97e76cc322 100644 --- a/qa/qa/resource/deploy_token.rb +++ b/qa/qa/resource/deploy_token.rb @@ -6,16 +6,16 @@ module QA attr_accessor :name, :expires_at attribute :username do - Page::Project::Settings::Repository.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.expand_deploy_tokens do |token| + Page::Project::Settings::Repository.perform do |repository_page| + repository_page.expand_deploy_tokens do |token| token.token_username end end end attribute :password do - Page::Project::Settings::Repository.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.expand_deploy_tokens do |token| + Page::Project::Settings::Repository.perform do |repository_page| + repository_page.expand_deploy_tokens do |token| token.token_password end end diff --git a/qa/qa/resource/file.rb b/qa/qa/resource/file.rb index a870e7d5d26..76c4c71c48d 100644 --- a/qa/qa/resource/file.rb +++ b/qa/qa/resource/file.rb @@ -27,11 +27,11 @@ module QA Page::Project::Show.perform(&:create_first_new_file!) - Page::File::Form.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.add_name(@name) - page.add_content(@content) - page.add_commit_message(@commit_message) - page.commit_changes + Page::File::Form.perform do |form| + form.add_name(@name) + form.add_content(@content) + form.add_commit_message(@commit_message) + form.commit_changes end end diff --git a/qa/qa/resource/fork.rb b/qa/qa/resource/fork.rb index d203e8eb264..73f1b0b9695 100644 --- a/qa/qa/resource/fork.rb +++ b/qa/qa/resource/fork.rb @@ -41,8 +41,8 @@ module QA fork_new.choose_namespace(user.name) end - Page::Layout::Banner.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.has_notice?('The project was successfully forked.') + Page::Layout::Banner.perform do |banner| + banner.has_notice?('The project was successfully forked.') end populate(:project) diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb index 7511396251d..c12e9dd146b 100644 --- a/qa/qa/resource/group.rb +++ b/qa/qa/resource/group.rb @@ -70,6 +70,10 @@ module QA } end + def api_delete_path + "/groups/#{id}" + end + def full_path sandbox.path + ' / ' + path end diff --git a/qa/qa/resource/kubernetes_cluster.rb b/qa/qa/resource/kubernetes_cluster.rb index 6778094cee4..1930e0465b2 100644 --- a/qa/qa/resource/kubernetes_cluster.rb +++ b/qa/qa/resource/kubernetes_cluster.rb @@ -24,36 +24,36 @@ module QA Page::Project::Operations::Kubernetes::Add.perform( &:add_existing_cluster) - Page::Project::Operations::Kubernetes::AddExisting.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.set_cluster_name(@cluster.cluster_name) - page.set_api_url(@cluster.api_url) - page.set_ca_certificate(@cluster.ca_certificate) - page.set_token(@cluster.token) - page.uncheck_rbac! unless @cluster.rbac - page.add_cluster! + Page::Project::Operations::Kubernetes::AddExisting.perform do |cluster_page| + cluster_page.set_cluster_name(@cluster.cluster_name) + cluster_page.set_api_url(@cluster.api_url) + cluster_page.set_ca_certificate(@cluster.ca_certificate) + cluster_page.set_token(@cluster.token) + cluster_page.uncheck_rbac! unless @cluster.rbac + cluster_page.add_cluster! end if @install_helm_tiller - Page::Project::Operations::Kubernetes::Show.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName + Page::Project::Operations::Kubernetes::Show.perform do |show| # We must wait a few seconds for permissions to be set up correctly for new cluster sleep 10 # Helm must be installed before everything else - page.install!(:helm) - page.await_installed(:helm) + show.install!(:helm) + show.await_installed(:helm) - page.install!(:ingress) if @install_ingress - page.install!(:prometheus) if @install_prometheus - page.install!(:runner) if @install_runner + show.install!(:ingress) if @install_ingress + show.install!(:prometheus) if @install_prometheus + show.install!(:runner) if @install_runner - page.await_installed(:ingress) if @install_ingress - page.await_installed(:prometheus) if @install_prometheus - page.await_installed(:runner) if @install_runner + show.await_installed(:ingress) if @install_ingress + show.await_installed(:prometheus) if @install_prometheus + show.await_installed(:runner) if @install_runner if @install_ingress populate(:ingress_ip) - page.set_domain("#{ingress_ip}.nip.io") - page.save_domain + show.set_domain("#{ingress_ip}.nip.io") + show.save_domain end end end diff --git a/qa/qa/resource/label.rb b/qa/qa/resource/label.rb index a9177ef3df6..6b0b0184130 100644 --- a/qa/qa/resource/label.rb +++ b/qa/qa/resource/label.rb @@ -28,11 +28,11 @@ module QA Page::Project::Menu.perform(&:go_to_labels) Page::Label::Index.perform(&:click_new_label_button) - Page::Label::New.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.fill_title(@title) - page.fill_description(@description) - page.fill_color(@color) - page.click_label_create_button + Page::Label::New.perform do |new_page| + new_page.fill_title(@title) + new_page.fill_description(@description) + new_page.fill_color(@color) + new_page.click_label_create_button end end diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb index 1a6de8de456..24fb96a20a2 100644 --- a/qa/qa/resource/merge_request.rb +++ b/qa/qa/resource/merge_request.rb @@ -65,17 +65,17 @@ module QA project.visit! Page::Project::Show.perform(&:new_merge_request) - Page::MergeRequest::New.perform do |new| - new.fill_title(@title) - new.fill_description(@description) - new.choose_milestone(@milestone) if @milestone - new.assign_to_me if @assignee == 'me' + Page::MergeRequest::New.perform do |new_page| + new_page.fill_title(@title) + new_page.fill_description(@description) + new_page.choose_milestone(@milestone) if @milestone + new_page.assign_to_me if @assignee == 'me' labels.each do |label| - new.select_label(label) + new_page.select_label(label) end - new.add_approval_rules(approval_rules) if approval_rules + new_page.add_approval_rules(approval_rules) if approval_rules - new.create_merge_request + new_page.create_merge_request end end diff --git a/qa/qa/resource/personal_access_token.rb b/qa/qa/resource/personal_access_token.rb index f5bebd25202..3b61b3f337c 100644 --- a/qa/qa/resource/personal_access_token.rb +++ b/qa/qa/resource/personal_access_token.rb @@ -16,10 +16,10 @@ module QA Page::Main::Menu.perform(&:click_settings_link) Page::Profile::Menu.perform(&:click_access_tokens) - Page::Profile::PersonalAccessTokens.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.fill_token_name(name || 'api-test-token') - page.check_api - page.click_create_token_button + Page::Profile::PersonalAccessTokens.perform do |token_page| + token_page.fill_token_name(name || 'api-test-token') + token_page.check_api + token_page.click_create_token_button end end end diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb index 3bebe2aaeda..f2ca0e0b8fd 100644 --- a/qa/qa/resource/project.rb +++ b/qa/qa/resource/project.rb @@ -32,14 +32,14 @@ module QA end attribute :repository_ssh_location do - Page::Project::Show.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.repository_clone_ssh_location + Page::Project::Show.perform do |show| + show.repository_clone_ssh_location end end attribute :repository_http_location do - Page::Project::Show.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.repository_clone_http_location + Page::Project::Show.perform do |show| + show.repository_clone_http_location end end @@ -48,7 +48,7 @@ module QA @standalone = false @description = 'My awesome project' @initialize_with_readme = false - @auto_devops_enabled = true + @auto_devops_enabled = false @visibility = 'public' end @@ -62,13 +62,13 @@ module QA Page::Group::Show.perform(&:go_to_new_project) end - Page::Project::New.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.choose_test_namespace - page.choose_name(@name) - page.add_description(@description) - page.set_visibility(@visibility) - page.enable_initialize_with_readme if @initialize_with_readme - page.create_new_project + Page::Project::New.perform do |new_page| + new_page.choose_test_namespace + new_page.choose_name(@name) + new_page.add_description(@description) + new_page.set_visibility(@visibility) + new_page.enable_initialize_with_readme if @initialize_with_readme + new_page.create_new_project end end @@ -115,8 +115,8 @@ module QA post_body end - def runners - response = get Runtime::API::Request.new(api_client, api_runners_path).url + def runners(tag_list: nil) + response = get Runtime::API::Request.new(api_client, "#{api_runners_path}?tag_list=#{tag_list.compact.join(',')}").url parse_body(response) end diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb index e4a9a8bcd3d..3e25235e6b8 100644 --- a/qa/qa/resource/project_imported_from_github.rb +++ b/qa/qa/resource/project_imported_from_github.rb @@ -17,18 +17,14 @@ module QA Page::Group::Show.perform(&:go_to_new_project) - Page::Project::New.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.click_import_project - end + Page::Project::New.perform(&:click_import_project) - Page::Project::New.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.click_github_link - end + Page::Project::New.perform(&:click_github_link) - Page::Project::Import::Github.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.add_personal_access_token(@personal_access_token) - page.list_repos - page.import!(@github_repository_path, @name) + Page::Project::Import::Github.perform do |import_page| + import_page.add_personal_access_token(@personal_access_token) + import_page.list_repos + import_page.import!(@github_repository_path, @name) end end end diff --git a/qa/qa/resource/project_milestone.rb b/qa/qa/resource/project_milestone.rb index 39077b64a22..11aad4ae65f 100644 --- a/qa/qa/resource/project_milestone.rb +++ b/qa/qa/resource/project_milestone.rb @@ -18,9 +18,9 @@ module QA def fabricate! project.visit! - Page::Project::Menu.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.click_issues - page.click_milestones + Page::Project::Menu.perform do |menu| + menu.click_issues + menu.click_milestones end Page::Project::Milestone::Index.perform(&:click_new_milestone) diff --git a/qa/qa/resource/runner.rb b/qa/qa/resource/runner.rb index 102c1ec83f5..d1b4e8f7d54 100644 --- a/qa/qa/resource/runner.rb +++ b/qa/qa/resource/runner.rb @@ -41,7 +41,17 @@ module QA end def remove_via_api! - @id = project.runners.find { |runner| runner[:description] == name }[:id] + runners = project.runners(tag_list: tags) + unless runners && !runners.empty? + raise "Project #{project.path_with_namespace} has no runners with tags #{tags}." + end + + this_runner = runners.find { |runner| runner[:description] == name } + unless this_runner + raise "Project #{project.path_with_namespace} does not have a runner with a description matching #{name} and tags #{tags}. Runners available: #{runners}" + end + + @id = this_runner[:id] super diff --git a/qa/qa/resource/settings/hashed_storage.rb b/qa/qa/resource/settings/hashed_storage.rb index 08bb95cfd4b..40c06768ffe 100644 --- a/qa/qa/resource/settings/hashed_storage.rb +++ b/qa/qa/resource/settings/hashed_storage.rb @@ -8,7 +8,7 @@ module QA raise ArgumentError unless traits.include?(:enabled) Page::Main::Login.perform(&:sign_in_using_credentials) - Page::Main::Menu.perform(&:click_admin_area) + Page::Main::Menu.perform(&:go_to_admin_area) Page::Admin::Menu.perform(&:go_to_repository_settings) Page::Admin::Settings::Repository.perform do |setting| diff --git a/qa/qa/resource/snippet.rb b/qa/qa/resource/snippet.rb index 23c17fdb32a..39be5e5cb7d 100644 --- a/qa/qa/resource/snippet.rb +++ b/qa/qa/resource/snippet.rb @@ -16,13 +16,13 @@ module QA def fabricate! Page::Dashboard::Snippet::Index.perform(&:go_to_new_snippet_page) - Page::Dashboard::Snippet::New.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.fill_title(@title) - page.fill_description(@description) - page.set_visibility(@visibility) - page.fill_file_name(@file_name) - page.fill_file_content(@file_content) - page.click_create_snippet_button + Page::Dashboard::Snippet::New.perform do |new_page| + new_page.fill_title(@title) + new_page.fill_description(@description) + new_page.set_visibility(@visibility) + new_page.fill_file_name(@file_name) + new_page.fill_file_content(@file_content) + new_page.click_create_snippet_button end end end diff --git a/qa/qa/resource/ssh_key.rb b/qa/qa/resource/ssh_key.rb index 9b6494c11bc..c140cb9ca62 100644 --- a/qa/qa/resource/ssh_key.rb +++ b/qa/qa/resource/ssh_key.rb @@ -17,8 +17,8 @@ module QA Page::Main::Menu.perform(&:click_settings_link) Page::Profile::Menu.perform(&:click_ssh_keys) - Page::Profile::SSHKeys.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.add_key(public_key, title) + Page::Profile::SSHKeys.perform do |profile_page| + profile_page.add_key(public_key, title) end end end diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb index bdbe5f3ef51..9544a3e80b3 100644 --- a/qa/qa/resource/user.rb +++ b/qa/qa/resource/user.rb @@ -79,7 +79,7 @@ module QA def api_delete super - QA::Runtime::Logger.debug("Deleted user '#{username}'") if Runtime::Env.debug? + QA::Runtime::Logger.debug("Deleted user '#{username}'") end def api_delete_path diff --git a/qa/qa/runtime/api/client.rb b/qa/qa/runtime/api/client.rb index 83fbb8f15d2..b9a3c9184aa 100644 --- a/qa/qa/runtime/api/client.rb +++ b/qa/qa/runtime/api/client.rb @@ -25,6 +25,23 @@ module QA end end + def self.as_admin + if Runtime::Env.admin_personal_access_token + Runtime::API::Client.new(:gitlab, personal_access_token: Runtime::Env.admin_personal_access_token) + else + user = Resource::User.fabricate_via_api! do |user| + user.username = Runtime::User.admin_username + user.password = Runtime::User.admin_password + end + + unless user.admin? + raise AuthorizationError, "User '#{user.username}' is not an administrator." + end + + Runtime::API::Client.new(:gitlab, user: user) + end + end + private def enable_ip_limits @@ -32,7 +49,7 @@ module QA Runtime::Browser.visit(@address, Page::Main::Login) Page::Main::Login.perform(&:sign_in_using_admin_credentials) - Page::Main::Menu.perform(&:click_admin_area) + Page::Main::Menu.perform(&:go_to_admin_area) Page::Admin::Menu.perform(&:go_to_network_settings) Page::Admin::Settings::Network.perform do |setting| diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb index 7e45e5e86ea..69ba90702be 100644 --- a/qa/qa/runtime/browser.rb +++ b/qa/qa/runtime/browser.rb @@ -132,6 +132,10 @@ module QA config.default_max_wait_time = CAPYBARA_MAX_WAIT_TIME # https://github.com/mattheworiordan/capybara-screenshot/issues/164 config.save_path = ::File.expand_path('../../tmp', __dir__) + + # Cabybara 3 does not normalize text by default, so older tests + # fail because of unexpected line breaks and other white space + config.default_normalize_ws = true end end @@ -152,6 +156,8 @@ module QA def perform(&block) visit(url) + simulate_slow_connection if Runtime::Env.simulate_slow_connection? + page_class.validate_elements_present! if QA::Runtime::Env.qa_cookies @@ -174,6 +180,28 @@ module QA def clear! visit(url) reset_session! + @network_conditions_configured = false + end + + private + + def simulate_slow_connection + return if @network_conditions_configured + + QA::Runtime::Logger.info( + <<~MSG.tr("\n", " ") + Simulating a slow connection with additional latency + of #{Runtime::Env.slow_connection_latency} ms and a maximum + throughput of #{Runtime::Env.slow_connection_throughput} kbps + MSG + ) + + Capybara.current_session.driver.browser.network_conditions = { + latency: Runtime::Env.slow_connection_latency, + throughput: Runtime::Env.slow_connection_throughput * 1000 + } + + @network_conditions_configured = true end end end diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb index bcd2a225469..184ccd3ef07 100644 --- a/qa/qa/runtime/env.rb +++ b/qa/qa/runtime/env.rb @@ -226,7 +226,7 @@ module QA end def gcloud_region - ENV.fetch('GCLOUD_REGION') + ENV['GCLOUD_REGION'] end def gcloud_num_nodes @@ -261,10 +261,30 @@ module QA ENV['QA_RUNTIME_SCENARIO_ATTRIBUTES'] end + def disable_rspec_retry? + enabled?(ENV['QA_DISABLE_RSPEC_RETRY'], default: false) + end + + def simulate_slow_connection? + enabled?(ENV['QA_SIMULATE_SLOW_CONNECTION'], default: false) + end + + def slow_connection_latency + ENV.fetch('QA_SLOW_CONNECTION_LATENCY_MS', 2000).to_i + end + + def slow_connection_throughput + ENV.fetch('QA_SLOW_CONNECTION_THROUGHPUT_KBPS', 32).to_i + end + def gitlab_qa_loop_runner_minutes ENV.fetch('GITLAB_QA_LOOP_RUNNER_MINUTES', 1).to_i end + def mailhog_hostname + ENV['MAILHOG_HOSTNAME'] + end + private def remote_grid_credentials diff --git a/qa/qa/runtime/ip_address.rb b/qa/qa/runtime/ip_address.rb new file mode 100644 index 00000000000..f370882e5c7 --- /dev/null +++ b/qa/qa/runtime/ip_address.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true +require 'socket' + +module QA + module Runtime + module IPAddress + include Support::Api + HostUnreachableError = Class.new(StandardError) + + LOOPBACK_ADDRESS = '127.0.0.1' + PUBLIC_IP_ADDRESS_API = "https://api.ipify.org" + + def fetch_current_ip_address + # When running on CI against a live environment such as staging.gitlab.com, + # we use the public facing IP address + ip_address = if Env.running_in_ci? && !URI.parse(Scenario.gitlab_address).host.include?('test') + response = get(PUBLIC_IP_ADDRESS_API) + raise HostUnreachableError, "#{PUBLIC_IP_ADDRESS_API} is unreachable" unless response.code == Support::Api::HTTP_STATUS_OK + + response.body + elsif page.current_host.include?('localhost') + LOOPBACK_ADDRESS + else + Socket.ip_address_list.detect { |intf| intf.ipv4_private? }.ip_address + end + + QA::Runtime::Logger.info "Current IP address: #{ip_address}" + + ip_address + end + end + end +end diff --git a/qa/qa/runtime/mail_hog.rb b/qa/qa/runtime/mail_hog.rb new file mode 100644 index 00000000000..899450a1540 --- /dev/null +++ b/qa/qa/runtime/mail_hog.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +module QA + module Runtime + module MailHog + def self.base_url + host = QA::Runtime::Env.mailhog_hostname || 'localhost' + "http://#{host}:8025" + end + + def self.api_messages_url + "#{base_url}/api/v2/messages" + end + end + end +end diff --git a/qa/qa/runtime/search.rb b/qa/qa/runtime/search.rb new file mode 100644 index 00000000000..faa110c96e7 --- /dev/null +++ b/qa/qa/runtime/search.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module QA + module Runtime + module Search + extend self + extend Support::Api + + ElasticSearchServerError = Class.new(RuntimeError) + + def elasticsearch_responding? + QA::Runtime::Logger.debug("Attempting to search via Elasticsearch...") + + QA::Support::Retrier.retry_on_exception do + # We don't care about the results of the search, we just need + # any search that uses Elasticsearch, not the native search + # The Elasticsearch-only scopes are blobs, wiki_blobs, and commits. + request = Runtime::API::Request.new(api_client, "/search?scope=blobs&search=foo") + response = get(request.url) + + unless response.code == singleton_class::HTTP_STATUS_OK + raise ElasticSearchServerError, "Search attempt failed. Request returned (#{response.code}): `#{response}`." + end + + true + end + end + + private + + def api_client + @api_client ||= Runtime::API::Client.new(:gitlab) + end + end + end +end diff --git a/qa/qa/scenario/test/integration/smtp.rb b/qa/qa/scenario/test/integration/smtp.rb new file mode 100644 index 00000000000..a27bb5f9368 --- /dev/null +++ b/qa/qa/scenario/test/integration/smtp.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module QA + module Scenario + module Test + module Integration + class SMTP < Test::Instance::All + tags :smtp + end + end + end + end +end diff --git a/qa/qa/service/cluster_provider/gcloud.rb b/qa/qa/service/cluster_provider/gcloud.rb index 9c82151666c..f0fb5eee6e3 100644 --- a/qa/qa/service/cluster_provider/gcloud.rb +++ b/qa/qa/service/cluster_provider/gcloud.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'active_support/inflector' + module QA module Service module ClusterProvider @@ -8,8 +10,22 @@ module QA find_executable('gcloud') || raise("You must first install `gcloud` executable to run these tests.") end + def initialize(rbac:) + super(rbac: rbac) + @attempts = 0 + @available_regions = %w( + asia-east1 asia-east2 + asia-northeast1 asia-south1 + asia-southeast1 australia-southeast1 + europe-west1 europe-west2 europe-west4 + northamerica-northeast1 southamerica-east1 + us-central1 us-east1 us-east4 + us-west1 us-west2 + ) + end + def set_credentials(admin_user) - master_auth = JSON.parse(`gcloud container clusters describe #{cluster_name} --region #{Runtime::Env.gcloud_region} --format 'json(masterAuth.username, masterAuth.password)'`) + master_auth = JSON.parse(`gcloud container clusters describe #{cluster_name} --region #{@region} --format 'json(masterAuth.username, masterAuth.password)'`) shell <<~CMD.tr("\n", ' ') kubectl config set-credentials #{admin_user} @@ -58,29 +74,41 @@ module QA end def create_cluster + @region = get_region + shell <<~CMD.tr("\n", ' ') gcloud container clusters create #{cluster_name} #{auth_options} --enable-basic-auth - --region #{Runtime::Env.gcloud_region} + --region #{@region} --disk-size 10GB --num-nodes #{Runtime::Env.gcloud_num_nodes} && gcloud container clusters get-credentials - --region #{Runtime::Env.gcloud_region} + --region #{@region} #{cluster_name} CMD + rescue QA::Service::Shellout::CommandError + @attempts += 1 + + retry unless @attempts > 1 + + raise $!, "Tried and failed to provision the cluster #{@attempts} #{"time".pluralize(@attempts)}.", $!.backtrace end def delete_cluster shell <<~CMD.tr("\n", ' ') gcloud container clusters delete - --region #{Runtime::Env.gcloud_region} + --region #{@region} #{cluster_name} --quiet --async CMD end + + def get_region + Runtime::Env.gcloud_region || @available_regions.delete(@available_regions.sample) + end end end end diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb index de33349a8b2..7143cc574b8 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb @@ -4,14 +4,13 @@ module QA context 'Configure', :orchestrated, :mattermost do describe 'Mattermost support' do it 'user creates a group with a mattermost team' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform(&:go_to_groups) - Page::Dashboard::Groups.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.click_new_group + Page::Dashboard::Groups.perform do |groups| + groups.click_new_group - expect(page).to have_content( + expect(groups).to have_content( /Create a Mattermost team for this group/ ) 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 index c9acd7df776..6f75940e1f0 100644 --- 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 @@ -4,8 +4,7 @@ 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.perform(&:sign_in_using_credentials) + Flow::Login.sign_in source_group = Resource::Group.fabricate_via_api! do |group| group.path = 'source-group' diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb index 6556c28ccab..1050005a231 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage', :smoke do describe 'basic user login' do it 'user logs in using basic credentials and logs out' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform do |menu| expect(menu).to have_personal_area @@ -14,11 +13,11 @@ module QA Support::Retrier.retry_until(sleep_interval: 0.5) do Page::Main::Menu.perform(&:sign_out) - Page::Main::Login.perform(&:has_sign_in_tab?) + Page::Main::Login.perform(&:can_sign_in?) end Page::Main::Login.perform do |form| - expect(form.sign_in_tab?).to be(true) + expect(form.can_sign_in?).to be(true) end end end diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb index 10cd8470a8f..46a0f1a4c8b 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage', :orchestrated, :ldap_no_tls, :ldap_tls do describe 'LDAP login' do it 'user logs into GitLab using LDAP credentials' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform do |menu| expect(menu).to have_personal_area diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb index babe6f7741f..a680cfa96bd 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb @@ -4,15 +4,14 @@ module QA context 'Manage', :orchestrated, :mattermost do describe 'Mattermost login' do it 'user logs into Mattermost using GitLab OAuth' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Support::Retrier.retry_on_exception do Runtime::Browser.visit(:mattermost, Page::Mattermost::Login) Page::Mattermost::Login.perform(&:sign_in_using_oauth) - Page::Mattermost::Main.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - expect(page).to have_content(/(Welcome to: Mattermost|Logout GitLab Mattermost)/) + Page::Mattermost::Main.perform do |mattermost| + expect(mattermost).to have_content(/(Welcome to: Mattermost|Logout GitLab Mattermost)/) 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 a118176eb8a..4fd80c353fb 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,7 +1,8 @@ # frozen_string_literal: true module QA - context 'Manage', :orchestrated, :oauth do + # Failure issue: https://gitlab.com/gitlab-org/gitlab/issues/36305 + context 'Manage', :orchestrated, :oauth, :skip 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/1_manage/project/add_project_member_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb index 07298b8a9be..9a273e9cd1c 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage' do describe 'Add project member' do it 'user adds project member' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) @@ -15,8 +14,8 @@ module QA project.visit! Page::Project::Menu.perform(&:go_to_members_settings) - Page::Project::Settings::Members.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.add_member(user.username) + Page::Project::Settings::Members.perform do |members| + members.add_member(user.username) end expect(page).to have_content(/@#{user.username}(\n| )?Given access/) diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb index fbe857dc2a5..9ca933a957f 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage', :smoke do describe 'Project creation' do it 'user creates a new project' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in created_project = Resource::Project.fabricate_via_browser_ui! do |project| project.name = 'awesome-project' diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb index 4f68500974e..e0045a4d8a1 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true module QA - # https://gitlab.com/gitlab-org/gitlab-foss/issues/58158 + # https://gitlab.com/gitlab-org/gitlab/issues/26952 + # BUG_IN_CODE context 'Manage', :github, :quarantine do describe 'Project import from GitHub' do let(:imported_project) do @@ -23,8 +24,7 @@ module QA end it 'user imports a GitHub repo' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in imported_project # import the project diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb index fe92fbd3ffe..5f3b492ea81 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage' do describe 'Project activity' do it 'user creates an event in the activity page upon Git push' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project_push = Resource::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' diff --git a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb new file mode 100644 index 00000000000..90290b4f2a0 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module QA + context 'Plan', :orchestrated, :smtp do + describe 'Email Notification' do + let(:user) do + Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) + end + + let(:project) do + Resource::Project.fabricate_via_api! do |resource| + resource.name = 'email-notification-test' + end + end + + before do + Flow::Login.sign_in + end + + it 'is received by a user for project invitation' do + Flow::Project.add_member(project: project, username: user.username) + + expect(page).to have_content(/@#{user.username}(\n| )?Given access/) + + # Wait for Action Mailer to deliver messages + mailhog_json = Support::Retrier.retry_until(sleep_interval: 1) do + Runtime::Logger.debug(%Q[retrieving "#{QA::Runtime::MailHog.api_messages_url}"]) + + mailhog_response = get QA::Runtime::MailHog.api_messages_url + + mailhog_data = JSON.parse(mailhog_response.body) + + # Expect at least two invitation messages: group and project + mailhog_data if mailhog_data.dig('total') >= 2 + end + + # Check json result from mailhog + mailhog_items = mailhog_json.dig('items') + expect(mailhog_items).to include(an_object_satisfying { |o| /project was granted/ === o.dig('Content', 'Headers', 'Subject', 0) }) + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb index 69389672a6d..494108dbefc 100644 --- a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb +++ b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb @@ -27,8 +27,8 @@ module QA project.visit! Page::Project::Show.perform(&:go_to_members_settings) - Page::Project::Settings::Members.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.add_member(user.username) + Page::Project::Settings::Members.perform do |members| + members.add_member(user.username) end issue = Resource::Issue.fabricate_via_api! do |issue| diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/close_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/close_issue_spec.rb index dc7fa9f3859..bab6b1ac5fc 100644 --- a/qa/qa/specs/features/browser_ui/2_plan/issue/close_issue_spec.rb +++ b/qa/qa/specs/features/browser_ui/2_plan/issue/close_issue_spec.rb @@ -3,19 +3,18 @@ module QA context 'Plan' do describe 'Close issue' do - let(:issue_title) { 'issue title' } - let(:commit_message) { 'Closes' } + let(:issue) do + Resource::Issue.fabricate_via_api! do |issue| + issue.title = 'Issue to be closed via pushing a commit' + end + end + + let(:project) { issue.project } + let(:issue_id) { issue.api_response[:iid] } before do Flow::Login.sign_in - issue = Resource::Issue.fabricate_via_api! do |issue| - issue.title = issue_title - end - - @project = issue.project - @issue_id = issue.api_response[:iid] - # Initial commit should be pushed because # the very first commit to the project doesn't close the issue # https://gitlab.com/gitlab-org/gitlab-foss/issues/38965 @@ -23,24 +22,15 @@ module QA end it 'user closes an issue by pushing commit' do - push_commit("#{commit_message} ##{@issue_id}", false) - - @project.visit! - Page::Project::Show.perform do |show| - show.click_commit(commit_message) - end - commit_sha = Page::Project::Commit::Show.perform(&:commit_sha) + push_commit("Closes ##{issue_id}", false) - Page::Project::Menu.perform(&:click_issues) - Page::Project::Issue::Index.perform do |index| - index.click_closed_issues_link - index.click_issue_link(issue_title) - end + issue.visit! Page::Project::Issue::Show.perform do |show| - show.select_all_activities_filter - expect(show).to have_element(:reopen_issue_button) - expect(show).to have_content("closed via commit #{commit_sha}") + reopen_issue_button_visible = show.wait(reload: true) do + show.has_element?(:reopen_issue_button, wait: 1.0) + end + expect(reopen_issue_button_visible).to be_truthy end end @@ -49,7 +39,7 @@ module QA push.commit_message = commit_message push.new_branch = new_branch push.file_content = commit_message - push.project = @project + push.project = project end end end diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb index e15afd1f576..9a1d13cf677 100644 --- a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb +++ b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb @@ -8,27 +8,19 @@ module QA before do Flow::Login.sign_in - project = Resource::Project.fabricate_via_api! do |resource| - resource.name = 'project-for-issue-suggestions' - resource.description = 'project for issue suggestions' - end - Resource::Issue.fabricate_via_api! do |issue| issue.title = issue_title - issue.project = project - end - - project.visit! + end.project.visit! end it 'user sees issue suggestions when creating a new issue' do Page::Project::Show.perform(&:go_to_new_issue) - Page::Project::Issue::New.perform do |new| - new.add_title("issue") - expect(new).to have_content(issue_title) + Page::Project::Issue::New.perform do |new_page| + new_page.add_title("issue") + expect(new_page).to have_content(issue_title) - new.add_title("Issue Board") - expect(new).not_to have_content(issue_title) + new_page.add_title("Issue Board") + expect(new_page).not_to have_content(issue_title) end end end 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 6969f123f95..eaa1a2a0da8 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 @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Create a new merge request' do before do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in @project = Resource::Project.fabricate_via_api! do |project| project.name = 'project' 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 6ca7af8a3af..370bf30f3a4 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 @@ -4,8 +4,7 @@ module QA 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) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in merge_request = Resource::MergeRequestFromFork.fabricate! do |merge_request| merge_request.fork_branch = 'feature-branch' diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb index c7b5e40d0be..e4c79bf75b5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true module QA - # Failure issue: https://gitlab.com/gitlab-org/quality/staging/issues/66 + # Failure issue: https://gitlab.com/gitlab-org/gitlab/issues/36817 + # BUG_IN_CODE context 'Create', :quarantine do describe 'Merge request rebasing' do it 'user rebases source branch of merge request' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate! do |project| project.name = "only-fast-forward" 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 a93f2695ec2..89f0fc37f3f 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 @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Merge request squashing' do it 'user squashes commits while merging' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate! do |project| project.name = "squash-before-merge" @@ -27,9 +26,11 @@ module QA merge_request.visit! - expect(page).to have_text('to be squashed') - Page::MergeRequest::Show.perform do |merge_request_page| + merge_request_page.retry_on_exception(reload: true) do + expect(merge_request_page).to have_text('to be squashed') + end + merge_request_page.mark_to_squash merge_request_page.merge! 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 d2fd1d743fb..d5346546efe 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 @@ -1,8 +1,7 @@ # frozen_string_literal: true module QA - # Failure issue: https://gitlab.com/gitlab-org/gitlab/issues/34551 - context 'Create', :quarantine do + context 'Create' do describe 'File templates' do include Runtime::Fixtures @@ -52,16 +51,16 @@ module QA Page::Project::Show.perform(&:create_new_file!) Page::File::Form.perform do |form| form.select_template template[:file_name], template[:name] - end - expect(page).to have_content(content[0..100]) + expect(form).to have_normalized_ws_text(content[0..100]) - Page::File::Form.perform(&:commit_changes) + form.commit_changes - expect(page).to have_content('The file has been successfully created.') - expect(page).to have_content(template[:file_name]) - expect(page).to have_content('Add new file') - expect(page).to have_content(content[0..100]) + expect(form).to have_content('The file has been successfully created.') + expect(form).to have_content(template[:file_name]) + expect(form).to have_content('Add new file') + expect(form).to have_normalized_ws_text(content[0..100]) + end end end end 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 3306c5f5c50..7b1c2a71158 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 @@ -16,8 +16,7 @@ module QA commit_message_of_third_branch = "Add #{file_third_branch}" before do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate! do |proj| proj.name = 'project-qa-test' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb index 56a7a04e840..474a7904fea 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb @@ -6,8 +6,7 @@ module QA let(:key_title) { "key for ssh tests #{Time.now.to_f}" } it 'user adds and then removes an SSH key', :smoke do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in key = Resource::SSHKey.fabricate! do |resource| resource.title = key_title diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb index ec3c4c1ae94..1f156dfe6d5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb @@ -2,12 +2,12 @@ module QA # Git protocol v2 is temporarily disabled - # https://gitlab.com/gitlab-org/gitlab-foss/issues/55769 (confidential) + # https://gitlab.com/gitlab-org/gitlab/issues/27828 + # BUG_IN_CODE context 'Create', :quarantine do describe 'Push over HTTP using Git protocol version 2', :requires_git_protocol_v2 do it 'user pushes to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in # Create a project to push to project = Resource::Project.fabricate! do |project| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb index 58f402a19ce..55c70656462 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb @@ -2,7 +2,8 @@ module QA # Git protocol v2 is temporarily disabled - # https://gitlab.com/gitlab-org/gitlab-foss/issues/55769 (confidential) + # https://gitlab.com/gitlab-org/gitlab/issues/27828 + # BUG_IN_CODE context 'Create', :quarantine do describe 'Push over SSH using Git protocol version 2', :requires_git_protocol_v2 do # Note: If you run this test against GDK make sure you've enabled sshd and @@ -17,20 +18,15 @@ module QA end end - def login - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) - end - around do |example| # Create an SSH key to be used with Git - login + Flow::Login.sign_in ssh_key example.run # Remove the SSH key - login + Flow::Login.sign_in Page::Main::Menu.perform(&:click_settings_link) Page::Profile::Menu.perform(&:click_ssh_keys) Page::Profile::SSHKeys.perform do |ssh_keys| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb index 1f4fb08accc..c713f11af7d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Git push over HTTP', :ldap_no_tls do it 'user using a personal access token pushes code to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in access_token = Resource::PersonalAccessToken.fabricate!.access_token diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb index 58e6c160a3a..2bd54d763a6 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Git push over HTTP', :ldap_no_tls do it 'user pushes code to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project_push = Resource::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb index a0251e1c385..1837a110d79 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb @@ -9,8 +9,7 @@ module QA let(:key_title) { "key for ssh tests #{Time.now.to_f}" } it 'user adds an ssh key and pushes code to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in key = Resource::SSHKey.fabricate! do |resource| resource.title = key_title 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 cbc9f63f772..277e7364ada 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 @@ -4,8 +4,7 @@ module QA context 'Create', :smoke do describe 'Snippet creation' do it 'User creates a snippet' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform(&:go_to_snippets) 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 318adc3c272..7c9db5ee496 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/gitlab/issues/34551 - context 'Create', :quarantine do + context 'Create' do describe 'Web IDE file templates' do include Runtime::Fixtures @@ -50,19 +49,19 @@ module QA @project.visit! Page::Project::Show.perform(&:open_web_ide!) - Page::Project::WebIDE::Edit.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.create_new_file_from_template template[:file_name], template[:name] + Page::Project::WebIDE::Edit.perform do |ide| + ide.create_new_file_from_template template[:file_name], template[:name] - expect(page.has_file?(template[:file_name])).to be_truthy - end + expect(ide.has_file?(template[:file_name])).to be_truthy - expect(page).to have_button('Undo') - expect(page).to have_content(content[0..100]) + expect(ide).to have_button('Undo') + expect(ide).to have_normalized_ws_text(content[0..100]) - Page::Project::WebIDE::Edit.perform(&:commit_changes) + ide.commit_changes - expect(page).to have_content(template[:file_name]) - expect(page).to have_content(content[0..100]) + expect(ide).to have_content(template[:file_name]) + expect(ide).to have_normalized_ws_text(content[0..100]) + end end end end diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb index 2c3f2c86c23..42aa527da85 100644 --- a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Wiki management' do it 'user creates, edits, clones, and pushes to the wiki' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in wiki = Resource::Wiki.fabricate! do |resource| resource.title = 'Home' @@ -16,9 +15,9 @@ module QA validate_content('My First Wiki Content') Page::Project::Wiki::Edit.perform(&:click_edit) - Page::Project::Wiki::New.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - page.set_content("My Second Wiki Content") - page.save_changes + Page::Project::Wiki::New.perform do |wiki| + wiki.set_content("My Second Wiki Content") + wiki.save_changes end validate_content('My Second Wiki Content') diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_ci_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_ci_variable_spec.rb index b2c70547421..c813484347e 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_ci_variable_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_ci_variable_spec.rb @@ -4,8 +4,7 @@ module QA context 'Verify' do describe 'CI variable support' do it 'user adds a CI variable', :smoke do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate_via_api! do |project| project.name = 'project-with-ci-variables' diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb index 5d91b70082c..d4853a7bcf3 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb @@ -10,8 +10,7 @@ module QA end it 'users creates a pipeline which gets processed' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate! do |project| project.name = 'project-with-pipelines' diff --git a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb index 58f129b846d..fb1ee4446a9 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb @@ -10,8 +10,7 @@ module QA end it 'user registers a new specific runner' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Resource::Runner.fabricate! do |runner| runner.name = executor diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb index 6f39a755392..9c964c726f1 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb @@ -4,8 +4,7 @@ module QA context 'Release' do describe 'Deploy key creation' do it 'user adds a deploy key' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in key = Runtime::Key::RSA.new deploy_key_title = 'deploy key title' diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb index 9dc4bcc8a03..3badaa983cb 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb @@ -10,8 +10,7 @@ module QA @job_log_json_flag_enabled = Runtime::Feature.enabled?('job_log_json') Runtime::Feature.disable('job_log_json') if @job_log_json_flag_enabled - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in @runner_name = "qa-runner-#{Time.now.to_i}" diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb index ec0c45652fd..9cb9f9ba529 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb @@ -4,8 +4,7 @@ module QA context 'Release' do describe 'Deploy token creation' do it 'user adds a deploy token' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in deploy_token_name = 'deploy token name' one_week_from_now = Date.today + 7 diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb index e9a3b0f75e6..a96bfde49f3 100644 --- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb +++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb @@ -4,11 +4,6 @@ require 'pathname' module QA context 'Configure' do - def login - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) - end - def disable_optional_jobs(project) # Disable code_quality check in Auto DevOps pipeline as it takes # too long and times out the test @@ -55,8 +50,7 @@ module QA end end - # https://gitlab.com/gitlab-org/gitlab/issues/35156 - describe 'Auto DevOps support', :orchestrated, :kubernetes, :quarantine do + describe 'Auto DevOps support', :orchestrated, :kubernetes do context 'when rbac is enabled' do before(:all) do @cluster = Service::KubernetesCluster.new.create! @@ -67,7 +61,7 @@ module QA end it 'runs auto devops' do - login + Flow::Login.sign_in @project = Resource::Project.fabricate! do |p| p.name = Runtime::Env.auto_devops_project_name || 'project-with-autodevops' @@ -149,7 +143,7 @@ module QA describe 'Auto DevOps', :smoke do before do - login + Flow::Login.sign_in @project = Resource::Project.fabricate_via_browser_ui! do |p| p.name = "project-with-autodevops-#{SecureRandom.hex(8)}" 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 187c4a2a248..b067a44e325 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 @@ -1,12 +1,12 @@ # frozen_string_literal: true module QA - context 'Performance bar' do + # https://gitlab.com/gitlab-org/gitlab/issues/38315 + context 'Performance bar', :quarantine do context 'when logged in as an admin user', :requires_admin do before do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_admin_credentials) - Page::Main::Menu.perform(&:click_admin_area) + Flow::Login.sign_in_as_admin + Page::Main::Menu.perform(&:go_to_admin_area) Page::Admin::Menu.perform(&:go_to_metrics_and_profiling_settings) Page::Admin::Settings::MetricsAndProfiling.perform do |setting| @@ -23,10 +23,10 @@ module QA issue.title = 'Performance bar test' end - Page::Layout::PerformanceBar.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - expect(page).to have_performance_bar - expect(page).to have_detailed_metrics - expect(page).to have_request_for('realtime_changes') # Always requested on issue pages + Page::Layout::PerformanceBar.perform do |bar_component| + expect(bar_component).to have_performance_bar + expect(bar_component).to have_detailed_metrics + expect(bar_component).to have_request_for('realtime_changes') # Always requested on issue pages end end end diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb index cd496efb4db..90924ffd40e 100644 --- a/qa/qa/support/api.rb +++ b/qa/qa/support/api.rb @@ -6,6 +6,7 @@ module QA HTTP_STATUS_OK = 200 HTTP_STATUS_CREATED = 201 HTTP_STATUS_NO_CONTENT = 204 + HTTP_STATUS_ACCEPTED = 202 def post(url, payload) RestClient::Request.execute( diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb index 6b6e12f86de..5d73d9635f8 100644 --- a/qa/qa/support/page/logging.rb +++ b/qa/qa/support/page/logging.rb @@ -49,8 +49,8 @@ module QA element end - def all_elements(name) - log("finding all :#{name}") + def all_elements(name, **kwargs) + log("finding all :#{name} with args #{kwargs}") elements = super @@ -59,6 +59,18 @@ module QA elements end + def check_element(name) + log("checking :#{name}") + + super + end + + def uncheck_element(name) + log("unchecking :#{name}") + + super + end + def click_element(name, page = nil, **kwargs) msg = ["clicking :#{name}"] msg << ", expecting to be at #{page.class}" if page @@ -99,10 +111,10 @@ module QA found end - def has_text?(text) + def has_text?(text, **kwargs) found = super - log(%Q{has_text?('#{text}') returned #{found}}) + log(%Q{has_text?('#{text}', wait: #{kwargs[:wait] || Capybara.default_max_wait_time}) returned #{found}}) found end diff --git a/qa/qa/tools/revoke_all_personal_access_tokens.rb b/qa/qa/tools/revoke_all_personal_access_tokens.rb index f14975c0e5e..e33d522bece 100644 --- a/qa/qa/tools/revoke_all_personal_access_tokens.rb +++ b/qa/qa/tools/revoke_all_personal_access_tokens.rb @@ -32,9 +32,9 @@ module QA token_name = 'api-test-token' - Page::Profile::PersonalAccessTokens.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName - while page.has_token_row_for_name?(token_name) - page.revoke_first_token_with_name(token_name) + Page::Profile::PersonalAccessTokens.perform do |tokens_page| + while tokens_page.has_token_row_for_name?(token_name) + tokens_page.revoke_first_token_with_name(token_name) print "\e[32m.\e[0m" end end diff --git a/qa/qa/vendor/saml_idp/page/login.rb b/qa/qa/vendor/saml_idp/page/login.rb index 9ebcabe15fc..041b4a0feee 100644 --- a/qa/qa/vendor/saml_idp/page/login.rb +++ b/qa/qa/vendor/saml_idp/page/login.rb @@ -8,7 +8,7 @@ module QA module Page class Login < Page::Base def login(username, password) - QA::Runtime::Logger.debug("Logging into SAMLIdp with username: #{username} and password:#{password}") if QA::Runtime::Env.debug? + QA::Runtime::Logger.debug("Logging into SAMLIdp with username: #{username} and password:#{password}") fill_in 'username', with: username fill_in 'password', with: password @@ -21,7 +21,7 @@ module QA def login_required? login_required = page.has_text?('Enter your username and password') - QA::Runtime::Logger.debug("login_required: #{login_required}") if QA::Runtime::Env.debug? + QA::Runtime::Logger.debug("login_required: #{login_required}") login_required end end diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb index 92a4f7b40e6..fb89bcd3ab4 100644 --- a/qa/spec/page/logging_spec.rb +++ b/qa/spec/page/logging_spec.rb @@ -117,7 +117,7 @@ describe QA::Support::Page::Logging do allow(page).to receive(:has_text?).and_return(true) expect { subject.has_text? 'foo' } - .to output(/has_text\?\('foo'\) returned true/).to_stdout_from_any_process + .to output(/has_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/).to_stdout_from_any_process end it 'logs has_no_text?' do diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb index 42f1e6f292a..3a26ed89e9c 100644 --- a/qa/spec/spec_helper.rb +++ b/qa/spec/spec_helper.rb @@ -20,7 +20,7 @@ RSpec.configure do |config| QA::Specs::Helpers::Quarantine.configure_rspec config.before do |example| - QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n") if QA::Runtime::Env.debug? + QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n") end config.after(:context) do @@ -62,7 +62,7 @@ RSpec.configure do |config| # show exception that triggers a retry if verbose_retry is set to true config.display_try_failure_messages = true - if ENV['CI'] + if ENV['CI'] && !QA::Runtime::Env.disable_rspec_retry? config.around do |example| retry_times = example.metadata.key?(:quarantine) ? 1 : 2 example.run_with_retry retry: retry_times |