summaryrefslogtreecommitdiff
path: root/qa/qa/page/project/settings/mirroring_repositories.rb
blob: ce369c90a9f65157f51bd8f363e1428050ebbf92 (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
# frozen_string_literal: true

module QA
  module Page
    module Project
      module Settings
        class MirroringRepositories < Page::Base
          view 'app/views/projects/mirrors/_authentication_method.html.haml' do
            element :authentication_method
            element :password
          end

          view 'app/views/projects/mirrors/_mirror_repos.html.haml' do
            element :mirror_repository_url_input
            element :mirror_repository_button
            element :mirror_repository_url_cell
            element :mirror_last_update_at_cell
            element :mirror_error_badge
            element :mirrored_repository_row
            element :copy_public_key_button
          end

          view 'app/views/projects/mirrors/_mirror_repos_form.html.haml' do
            element :mirror_direction
          end

          view 'app/views/shared/_remote_mirror_update_button.html.haml' do
            element :update_now_button
            element :updating_button
          end

          view 'app/views/projects/mirrors/_ssh_host_keys.html.haml' do
            element :detect_host_keys
            element :fingerprints_list
          end

          view 'app/views/projects/mirrors/_authentication_method.html.haml' do
            element :authentication_method
            element :password
          end

          def repository_url=(value)
            fill_element :mirror_repository_url_input, value
          end

          def password=(value)
            fill_element :password, value
          end

          def mirror_direction=(value)
            raise ArgumentError, "Mirror direction must be 'Push' or 'Pull'" unless %w(Push Pull).include? value

            select_element(:mirror_direction, value)

            # Changing the mirror direction causes the fields below to change,
            # and that change is animated, so we need to wait for the animation
            # to complete otherwise changes to those fields could fail
            wait_for_animated_element :authentication_method
          end

          def authentication_method=(value)
            raise ArgumentError, "Authentication method must be 'SSH public key', 'Password', or 'None'" unless %w(Password None SSH\ public\ key).include? value

            select_element(:authentication_method, value)
          end

          def public_key(url)
            row_index = find_repository_row_index url

            within_element_by_index(:mirrored_repository_row, row_index) do
              find_element(:copy_public_key_button)['data-clipboard-text']
            end
          end

          def detect_host_keys
            click_element :detect_host_keys

            # The host key detection process is interrupted if we navigate away
            # from the page before the fingerprint appears.
            find_element(:fingerprints_list, text: /.*/, wait: 60)
          end

          def mirror_repository
            click_element :mirror_repository_button
          end

          def update(url)
            row_index = find_repository_row_index url

            within_element_by_index(:mirrored_repository_row, row_index) do
              # When a repository is first mirrored, the update process might
              # already be started, so the button is already "clicked"
              click_element :update_now_button unless has_element? :updating_button
            end

            # Wait a few seconds for the sync to occur and then refresh the page
            # so that 'last update' shows 'just now' or a period in seconds
            sleep 5
            refresh

            wait_until(max_duration: 180, sleep_interval: 1) do
              within_element_by_index(:mirrored_repository_row, row_index) do
                last_update = find_element(:mirror_last_update_at_cell, wait: 0)
                last_update.has_text?('just now') || last_update.has_text?('seconds')
              end
            end

            # Fail early if the page still shows that there has been no update
            within_element_by_index(:mirrored_repository_row, row_index) do
              find_element(:mirror_last_update_at_cell, wait: 0).assert_no_text('Never')
              assert_no_element(:mirror_error_badge)
            end
          end

          private

          def find_repository_row_index(target_url)
            wait_until(max_duration: 5, reload: false) do
              all_elements(:mirror_repository_url_cell, minimum: 1).index do |url|
                # The url might be a sanitized url but the target_url won't be so
                # we compare just the paths instead of the full url
                URI.parse(url.text).path == target_url.path
              end
            end
          end
        end
      end
    end
  end
end

QA::Page::Project::Settings::MirroringRepositories.prepend_if_ee('QA::EE::Page::Project::Settings::MirroringRepositories')