Welcome to mirror list, hosted at ThFree Co, Russian Federation.

spec_helper.rb « specs « qa « qa - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d4295ce72e7478357b9046a3bc9a566700c55d3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# frozen_string_literal: true

require 'active_support/testing/time_helpers'
require 'factory_bot'

require_relative '../../qa'

# Require shared test tooling from Rails test suite
require_relative '../../../spec/support/fast_quarantine'

QA::Specs::QaDeprecationToolkitEnv.configure!

Knapsack::Adapters::RSpecAdapter.bind if QA::Runtime::Env.knapsack?

# TODO: move all classes that perform rspec configuration under spec/helpers
QA::Support::GitlabAddress.define_gitlab_address_attribute!
QA::Runtime::Browser.configure!
QA::Specs::Helpers::FeatureSetup.configure!
QA::Runtime::AllureReport.configure!
QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
QA::Service::DockerRun::Video.configure!

# Enable zero monkey patching mode before loading any other RSpec code.
RSpec.configure(&:disable_monkey_patching!)

# For JH additionally process when `jh/` exists
require_relative('../../../jh/qa/qa/specs/spec_helper') if GitlabEdition.jh?

RSpec.configure do |config|
  config.include ActiveSupport::Testing::TimeHelpers
  config.include QA::Support::Matchers::EventuallyMatcher
  config.include QA::Support::Matchers::HaveMatcher
  config.include FactoryBot::Syntax::Methods

  FactoryBot.definition_file_paths = ['qa/factories']

  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::TestMetricsFormatter if QA::Runtime::Env.running_in_ci?

  config.prepend_before do |example|
    QA::Runtime::Logger.info("Starting test: #{Rainbow(example.full_description).bright}")
    QA::Runtime::Example.current = example

    visit(QA::Runtime::Scenario.gitlab_address) if QA::Runtime::Env.mobile_layout?

    # Reset fabrication counters tracked in resource base
    Thread.current[:api_fabrication] = 0
    Thread.current[:browser_ui_fabrication] = 0
  end

  config.prepend_before(:suite) do
    # Perform before hooks at the very start of the test run
    QA::Runtime::Release.perform_before_hooks unless QA::Runtime::Env.dry_run
  end

  config.before(:suite) do
    FactoryBot.find_definitions
  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

  config.prepend_after do |example|
    page = Capybara.page
    QA::Support::PageErrorChecker.log_request_errors(page)

    QA::Support::PageErrorChecker.check_page_for_error_code(page) if example.exception
  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?)
  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.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.match?(/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

Dir[::File.join(__dir__, "features/shared_examples/**/*.rb")].each { |f| require f }
Dir[::File.join(__dir__, "features/shared_contexts/**/*.rb")].each { |f| require f }