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

merge_when_pipeline_succeeds_spec.rb « merge_request « 3_create « browser_ui « features « specs « qa « qa - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 85270791f0f8bf17324540c2e02aaed1c8aea497 (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
# frozen_string_literal: true

module QA
  RSpec.describe 'Create', :runner do
    describe 'Merge requests' do
      shared_examples 'merge when pipeline succeeds' do |repeat: 1|
        let(:project) do
          Resource::Project.fabricate_via_api! do |project|
            project.name = 'merge-when-pipeline-succeeds'
            project.initialize_with_readme = true
          end
        end

        let!(:runner) do
          Resource::Runner.fabricate! do |runner|
            runner.project = project
            runner.name = "runner-for-#{project.name}"
            runner.tags = ["runner-for-#{project.name}"]
          end
        end

        before do
          Flow::Login.sign_in
        end

        after do
          runner&.remove_via_api!
          project&.remove_via_api!
        end

        it 'merges after pipeline succeeds' do
          transient_test = repeat > 1

          # Push a new pipeline config file
          Resource::Repository::Commit.fabricate_via_api! do |commit|
            commit.project = project
            commit.commit_message = 'Add .gitlab-ci.yml'
            commit.add_files(
              [
                {
                  file_path: '.gitlab-ci.yml',
                  content: <<~EOF
                    test:
                      tags: ["runner-for-#{project.name}"]
                      script: sleep 30
                      only:
                        - merge_requests
                  EOF
                }
              ]
            )
          end

          repeat.times do |i|
            QA::Runtime::Logger.info("Transient bug test - Trial #{i}") if transient_test

            branch_name = "mr-test-#{SecureRandom.hex(6)}-#{i}"

            # Create a branch that will be merged into the default branch
            Resource::Repository::ProjectPush.fabricate! do |project_push|
              project_push.project = project
              project_push.new_branch = true
              project_push.branch_name = branch_name
              project_push.file_name = "#{branch_name}.txt"
            end

            # Create a merge request to merge the branch we just created
            merge_request = Resource::MergeRequest.fabricate_via_api! do |merge_request|
              merge_request.project = project
              merge_request.source_branch = branch_name
              merge_request.no_preparation = true
            end

            # Load the page so that the browser is as prepared as possible to display the pipeline in progress when we
            # start it.
            merge_request.visit!

            # Push a new file to trigger a new pipeline
            Resource::Repository::Commit.fabricate_via_api! do |commit|
              commit.project = project
              commit.commit_message = 'Add new file'
              commit.branch = branch_name
              commit.add_files(
                [
                  {
                    file_path: "#{branch_name}-file.md",
                    content: "file content"
                  }
                ]
              )
            end

            Page::MergeRequest::Show.perform do |mr|
              mr.refresh

              # Part of the challenge with this test is that the MR widget has many components that could be displayed
              # and many errors states that those components could encounter. Most of the time few of those
              # possible components will be relevant, so it would be inefficient for this test to check for each of
              # them. Instead, we fail on anything but the expected state.
              #
              # The following method allows us to handle and ignore states (as we find them) that users could safely ignore.
              mr.wait_until_ready_to_merge(transient_test: transient_test)

              mr.retry_until(reload: true, message: 'Wait until ready to click MWPS') do
                merge_request.reload!

                # Click the MWPS button if we can
                break mr.merge_when_pipeline_succeeds! if mr.has_element?(:merge_button, text: 'Merge when pipeline succeeds')

                # But fail if the button is missing because the pipeline is complete
                raise "The pipeline already finished before we could click MWPS" if mr.wait_until { project.pipelines.first }[:status] == 'success'

                # Otherwise, if this is not a transient test reload the page and retry
                next false unless transient_test
              end

              aggregate_failures do
                expect { mr.merged? }.to eventually_be_truthy.within(max_duration: 60), "Expected content 'The changes were merged' but it did not appear."
                expect(merge_request.reload!.merge_when_pipeline_succeeds).to be_truthy
                expect(merge_request.state).to eq('merged')
                expect(project.pipelines.last[:status]).to eq('success')
              end
            end
          end
        end
      end

      context 'when merging once', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347686' do
        it_behaves_like 'merge when pipeline succeeds'
      end

      context 'when merging several times', :transient, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347641' do
        it_behaves_like 'merge when pipeline succeeds', repeat: Runtime::Env.transient_trials
      end
    end
  end
end