summaryrefslogtreecommitdiff
path: root/qa/qa/specs/spec_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'qa/qa/specs/spec_helper.rb')
-rw-r--r--qa/qa/specs/spec_helper.rb136
1 files changed, 136 insertions, 0 deletions
diff --git a/qa/qa/specs/spec_helper.rb b/qa/qa/specs/spec_helper.rb
new file mode 100644
index 00000000000..b130fff0488
--- /dev/null
+++ b/qa/qa/specs/spec_helper.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require_relative '../../qa'
+
+require_relative 'qa_deprecation_toolkit_env'
+QaDeprecationToolkitEnv.configure!
+
+Knapsack::Adapters::RSpecAdapter.bind if QA::Runtime::Env.knapsack?
+
+QA::Support::GitlabAddress.define_gitlab_address_attribute!
+QA::Runtime::Browser.configure! unless QA::Runtime::Env.dry_run
+QA::Runtime::AllureReport.configure!
+QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
+
+Dir[::File.join(__dir__, "features/shared_examples/*.rb")].sort.each { |f| require f }
+Dir[::File.join(__dir__, "features/shared_contexts/*.rb")].sort.each { |f| require f }
+
+RSpec.configure do |config|
+ config.include QA::Support::Matchers::EventuallyMatcher
+ config.include QA::Support::Matchers::HaveMatcher
+
+ config.add_formatter QA::Support::Formatters::ContextFormatter
+ config.add_formatter QA::Support::Formatters::QuarantineFormatter
+ config.add_formatter QA::Support::Formatters::FeatureFlagFormatter
+ config.add_formatter QA::Support::Formatters::TestStatsFormatter if QA::Runtime::Env.export_metrics?
+
+ config.before(:suite) do |suite|
+ QA::Resource::ReusableCollection.register_resource_classes do |collection|
+ QA::Resource::ReusableProject.register(collection)
+ QA::Resource::ReusableGroup.register(collection)
+ end
+ end
+
+ config.prepend_before do |example|
+ QA::Runtime::Logger.info("Starting test: #{Rainbow(example.full_description).bright}")
+ QA::Runtime::Example.current = example
+
+ # Reset fabrication counters tracked in resource base
+ Thread.current[:api_fabrication] = 0
+ Thread.current[:browser_ui_fabrication] = 0
+ end
+
+ config.after do
+ # If a .netrc file was created during the test, delete it so that subsequent tests don't try to use the same logins
+ QA::Git::Repository.new.delete_netrc
+ end
+
+ # Add fabrication time to spec metadata
+ config.append_after do |example|
+ example.metadata[:api_fabrication] = Thread.current[:api_fabrication]
+ example.metadata[:browser_ui_fabrication] = Thread.current[:browser_ui_fabrication]
+ end
+
+ config.after(:context) do
+ if !QA::Runtime::Browser.blank_page? && QA::Page::Main::Menu.perform(&:signed_in?)
+ QA::Page::Main::Menu.perform(&:sign_out)
+ raise(
+ <<~ERROR
+ The test left the browser signed in.
+
+ Usually, Capybara prevents this from happening but some things can
+ interfere. For example, if it has an `after(:context)` block that logs
+ in, the browser will stay logged in and this will cause the next test
+ to fail.
+
+ Please make sure the test does not leave the browser signed in.
+ ERROR
+ )
+ end
+ end
+
+ config.after(:suite) do |suite|
+ # Write all test created resources to JSON file
+ QA::Tools::TestResourceDataProcessor.write_to_file(suite.reporter.failed_examples.any?)
+
+ # If requested, confirm that resources were used appropriately (e.g., not left with changes that interfere with
+ # further reuse)
+ QA::Resource::ReusableCollection.validate_resource_reuse if QA::Runtime::Env.validate_resource_reuse?
+
+ # If any tests failed, leave the resources behind to help troubleshoot, otherwise remove them.
+ # Do not remove the shared resource on live environments
+ begin
+ next if suite.reporter.failed_examples.present?
+ next unless QA::Runtime::Scenario.attributes.include?(:gitlab_address)
+ next if QA::Runtime::Env.running_on_dot_com?
+
+ QA::Resource::ReusableCollection.remove_all_via_api!
+ rescue QA::Resource::Errors::InternalServerError => e
+ # Temporarily prevent this error from failing jobs while the cause is investigated
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/354387
+ QA::Runtime::Logger.debug(e.message)
+ end
+ end
+
+ config.append_after(:suite) do
+ QA::Support::KnapsackReport.move_regenerated_report if QA::Runtime::Env.knapsack?
+ end
+
+ config.expect_with :rspec do |expectations|
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+ end
+
+ config.mock_with :rspec do |mocks|
+ mocks.verify_partial_doubles = true
+ end
+
+ config.shared_context_metadata_behavior = :apply_to_host_groups
+ config.disable_monkey_patching!
+ config.expose_dsl_globally = true
+ config.profile_examples = 10
+ config.order = :random
+ Kernel.srand config.seed
+
+ # This option allows to use shorthand aliases for adding :focus metadata - fit, fdescribe and fcontext
+ config.filter_run_when_matching :focus
+
+ if ENV['CI'] && !QA::Runtime::Env.disable_rspec_retry?
+ # show retry status in spec process
+ config.verbose_retry = true
+
+ # show exception that triggers a retry if verbose_retry is set to true
+ config.display_try_failure_messages = true
+
+ non_quarantine_retries = QA::Runtime::Env.ci_project_name =~ /staging|canary|production/ ? 3 : 2
+ config.around do |example|
+ quarantine = example.metadata[:quarantine]
+ different_quarantine_context = QA::Specs::Helpers::Quarantine.quarantined_different_context?(quarantine)
+ focused_quarantine = QA::Specs::Helpers::Quarantine.filters.key?(:quarantine)
+
+ # Do not disable retry when spec is quarantined but on different environment
+ next example.run_with_retry(retry: non_quarantine_retries) if different_quarantine_context && !focused_quarantine
+
+ example.run_with_retry(retry: quarantine ? 1 : non_quarantine_retries)
+ end
+ end
+end