diff options
author | João Cunha <j.a.cunha@gmail.com> | 2019-02-26 10:33:32 +0000 |
---|---|---|
committer | João Cunha <j.a.cunha@gmail.com> | 2019-02-26 10:33:32 +0000 |
commit | ed7065bbdb6f6fad3cc8fb369267fa811767c8a5 (patch) | |
tree | b3fda377c51504a6d21da1742cac3de7fd668ef0 /qa/qa | |
parent | 26c7d04cd06d1126e4a4a7a1c9308d12de77172e (diff) | |
parent | 094d740886eaf62fd219dacd11aa9a966758a962 (diff) | |
download | gitlab-ce-ed7065bbdb6f6fad3cc8fb369267fa811767c8a5.tar.gz |
Merge branch 'master' into 56937-edit-knative-domain-after-it-has-been-deployed56937-edit-knative-domain-after-it-has-been-deployed
Diffstat (limited to 'qa/qa')
45 files changed, 283 insertions, 154 deletions
diff --git a/qa/qa/ce/strategy.rb b/qa/qa/ce/strategy.rb index 6d1601dfa48..e0fbbed2567 100644 --- a/qa/qa/ce/strategy.rb +++ b/qa/qa/ce/strategy.rb @@ -8,7 +8,10 @@ module QA end def perform_before_hooks - # noop + # The login page could take some time to load the first time it is visited. + # We visit the login page and wait for it to properly load only once before the tests. + QA::Runtime::Browser.visit(:gitlab, QA::Page::Main::Login) + QA::Page::Main::Login.perform(&:assert_page_loaded) end end end diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index b1f27131207..05e38aba77d 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -18,22 +18,13 @@ module QA page.refresh end - def wait(max: 60, time: 0.1, reload: true) - start = Time.now - - while Time.now - start < max - result = yield - return result if result - - sleep(time) - - refresh if reload + def wait(max: 60, interval: 0.1, reload: true) + QA::Support::Waiter.wait(max: max, interval: interval) do + yield || (reload && refresh && false) end - - false end - def with_retry(max_attempts: 3, reload: false) + def retry_until(max_attempts: 3, reload: false) attempts = 0 while attempts < max_attempts @@ -48,6 +39,12 @@ module QA false end + def retry_on_exception(max_attempts: 3, reload: false, sleep_interval: 0.5) + QA::Support::Retrier.retry_on_exception(max_attempts: max_attempts, reload_page: (reload && self), sleep_interval: sleep_interval) do + yield + end + end + def scroll_to(selector, text: nil) page.execute_script <<~JS var elements = Array.from(document.querySelectorAll('#{selector}')); @@ -73,7 +70,7 @@ module QA xhr.send(); JS - return false unless wait(time: 0.5, max: 60, reload: false) do + return false unless wait(interval: 0.5, max: 60, reload: false) do page.evaluate_script('xhr.readyState == XMLHttpRequest.DONE') end @@ -156,6 +153,10 @@ module QA click_link text end + def click_body + find('body').click + end + def self.path raise NotImplementedError end diff --git a/qa/qa/page/component/clone_panel.rb b/qa/qa/page/component/clone_panel.rb index d37b63c716a..b80877f5ecd 100644 --- a/qa/qa/page/component/clone_panel.rb +++ b/qa/qa/page/component/clone_panel.rb @@ -21,11 +21,6 @@ module QA repository_clone_location(:ssh_clone_url) end - def wait_for_push - sleep 5 - refresh - end - private def repository_clone_location(kind) diff --git a/qa/qa/page/component/legacy_clone_panel.rb b/qa/qa/page/component/legacy_clone_panel.rb index 99132190f3f..e495cf4ef04 100644 --- a/qa/qa/page/component/legacy_clone_panel.rb +++ b/qa/qa/page/component/legacy_clone_panel.rb @@ -27,11 +27,6 @@ module QA Git::Location.new(find('#project_clone').value) end - def wait_for_push - sleep 5 - refresh - end - private def choose_repository_clone(kind, detect_text) diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb index 6dd9ff997a4..9d6bd338027 100644 --- a/qa/qa/page/group/show.rb +++ b/qa/qa/page/group/show.rb @@ -45,15 +45,17 @@ module QA private def select_kind(kind) - within_element(:new_project_or_subgroup_dropdown) do - # May need to click again because it is possible to click the button quicker than the JS is bound - wait(reload: false) do - click_element :new_project_or_subgroup_dropdown_toggle + retry_on_exception(sleep_interval: 1.0) do + within_element(:new_project_or_subgroup_dropdown) do + # May need to click again because it is possible to click the button quicker than the JS is bound + wait(reload: false) do + click_element :new_project_or_subgroup_dropdown_toggle - has_element?(kind) - end + has_element?(kind) + end - click_element kind + click_element kind + end end end end diff --git a/qa/qa/page/label/index.rb b/qa/qa/page/label/index.rb index f0d323ca3b4..de0cfa9f293 100644 --- a/qa/qa/page/label/index.rb +++ b/qa/qa/page/label/index.rb @@ -14,6 +14,10 @@ module QA element :label_svg end + view 'app/views/shared/empty_states/_priority_labels.html.haml' do + element :label_svg + end + def go_to_new_label # The 'labels.svg' takes a fraction of a second to load after which the "New label" button shifts up a bit # This can cause webdriver to miss the hit so we wait for the svg to load (implicitly with has_element?) diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb index e476cbe29a2..e03fe9ab83a 100644 --- a/qa/qa/page/main/login.rb +++ b/qa/qa/page/main/login.rb @@ -40,6 +40,12 @@ module QA element :login_page end + def assert_page_loaded + unless page_loaded? + raise QA::Runtime::Browser::NotRespondingError, "Login page did not load at #{QA::Page::Main::Login.perform(&:current_url)}" + end + end + def page_loaded? wait(max: 60) do has_element?(:login_page) diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb index 616d50f47fc..55500e831c6 100644 --- a/qa/qa/page/main/menu.rb +++ b/qa/qa/page/main/menu.rb @@ -57,7 +57,7 @@ module QA end def go_to_profile_settings - with_retry(reload: false) do + retry_until(reload: false) do within_user_menu do click_link 'Settings' end diff --git a/qa/qa/page/main/sign_up.rb b/qa/qa/page/main/sign_up.rb index 9ca498012eb..46a105003d0 100644 --- a/qa/qa/page/main/sign_up.rb +++ b/qa/qa/page/main/sign_up.rb @@ -23,7 +23,7 @@ module QA check_element :new_user_accept_terms if has_element?(:new_user_accept_terms) - signed_in = with_retry do + signed_in = retry_until do click_element :new_user_register_button Page::Main::Menu.act { has_personal_area? } diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index f54bea880a0..976e431186d 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -148,7 +148,7 @@ module QA end def add_comment_to_diff(text) - wait(time: 5) do + wait(interval: 5) do has_text?("No newline at end of file") end all_elements(:new_diff_line).first.hover diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb index a3cde73d3f2..488157d9878 100644 --- a/qa/qa/page/project/import/github.rb +++ b/qa/qa/page/project/import/github.rb @@ -10,12 +10,11 @@ module QA element :list_repos_button, "submit_tag _('List your GitHub repositories')" # rubocop:disable QA/ElementWithPattern end - view 'app/views/import/_githubish_status.html.haml' do - element :project_import_row, 'data: { qa: { repo_path: repo.full_name } }' # rubocop:disable QA/ElementWithPattern + view 'app/assets/javascripts/import_projects/components/provider_repo_table_row.vue' do + element :project_import_row element :project_namespace_select - element :project_namespace_field, 'select_tag :namespace_id' # rubocop:disable QA/ElementWithPattern - element :project_path_field, 'text_field_tag :path, sanitize_project_name(repo.name)' # rubocop:disable QA/ElementWithPattern - element :import_button, "_('Import')" # rubocop:disable QA/ElementWithPattern + element :project_path_field + element :import_button end def add_personal_access_token(personal_access_token) diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb index 1028cc045a0..1c25be5fd0c 100644 --- a/qa/qa/page/project/issue/show.rb +++ b/qa/qa/page/project/issue/show.rb @@ -37,18 +37,25 @@ module QA end def select_comments_only_filter - click_element :discussion_filter - find_element(:filter_options, "Show comments only").click + select_filter_with_text('Show comments only') end def select_history_only_filter - click_element :discussion_filter - find_element(:filter_options, "Show history only").click + select_filter_with_text('Show history only') end def select_all_activities_filter - click_element :discussion_filter - find_element(:filter_options, "Show all activity").click + select_filter_with_text('Show all activity') + end + + private + + def select_filter_with_text(text) + retry_on_exception do + click_body + click_element :discussion_filter + find_element(:filter_options, text).click + end end end end diff --git a/qa/qa/page/project/job/show.rb b/qa/qa/page/project/job/show.rb index 49c676c01f2..9c218f4ed8b 100644 --- a/qa/qa/page/project/job/show.rb +++ b/qa/qa/page/project/job/show.rb @@ -4,10 +4,6 @@ module QA::Page COMPLETED_STATUSES = %w[passed failed canceled blocked skipped manual].freeze # excludes created, pending, running PASSED_STATUS = 'passed'.freeze - view 'app/assets/javascripts/jobs/components/job_app.vue' do - element :loading_animation - end - view 'app/assets/javascripts/jobs/components/job_log.vue' do element :build_trace end @@ -20,22 +16,13 @@ module QA::Page element :pipeline_path end - def completed? - COMPLETED_STATUSES.include?(status_badge) - end - def successful?(timeout: 60) - wait(reload: false, max: timeout) do - completed? && !trace_loading? - end + raise "Timed out waiting for the build trace to load" unless loaded? + raise "Timed out waiting for the status to be a valid completed state" unless completed?(timeout: timeout) status_badge == PASSED_STATUS end - def trace_loading? - has_element?(:loading_animation) - end - # Reminder: You may wish to wait for a particular job status before checking output def output find_element(:build_trace).text @@ -43,6 +30,16 @@ module QA::Page private + def loaded?(wait: 60) + has_element?(:build_trace, wait: wait) + end + + def completed?(timeout: 60) + wait(reload: false, max: timeout) do + COMPLETED_STATUSES.include?(status_badge) + end + end + def status_badge find_element(:status_badge).text end diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb index a588af07e4a..9f1867ef8a5 100644 --- a/qa/qa/page/project/new.rb +++ b/qa/qa/page/project/new.rb @@ -26,7 +26,7 @@ module QA def choose_test_namespace click_element :project_namespace_select - select_item(Runtime::Namespace.path) + search_and_select(Runtime::Namespace.path) end def go_to_import_project diff --git a/qa/qa/page/project/operations/kubernetes/show.rb b/qa/qa/page/project/operations/kubernetes/show.rb index 98ac5c32d91..d4e1679b6bf 100644 --- a/qa/qa/page/project/operations/kubernetes/show.rb +++ b/qa/qa/page/project/operations/kubernetes/show.rb @@ -14,6 +14,11 @@ module QA element :ingress_ip_address, 'id="ingress-ip-address"' # rubocop:disable QA/ElementWithPattern end + view 'app/views/clusters/clusters/_form.html.haml' do + element :base_domain + element :save_domain + end + def install!(application_name) within(".js-cluster-application-row-#{application_name}") do page.has_button?('Install', wait: 30) @@ -32,6 +37,14 @@ module QA # ip address is assigned for the ingress controller page.find('#ingress-ip-address', wait: 1200).value end + + def set_domain(domain) + fill_element :base_domain, domain + end + + def save_domain + click_element :save_domain + end end end end diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb index a73be7dfeda..831166f6373 100644 --- a/qa/qa/page/project/settings/mirroring_repositories.rb +++ b/qa/qa/page/project/settings/mirroring_repositories.rb @@ -62,7 +62,7 @@ module QA sleep 5 refresh - wait(time: 1) do + wait(interval: 1) do within_element_by_index(:mirrored_repository_row, row_index) do last_update = find_element(:mirror_last_update_at, wait: 0) last_update.has_text?('just now') || last_update.has_text?('seconds') diff --git a/qa/qa/page/project/web_ide/edit.rb b/qa/qa/page/project/web_ide/edit.rb index a3e126b51da..2b6c01888d5 100644 --- a/qa/qa/page/project/web_ide/edit.rb +++ b/qa/qa/page/project/web_ide/edit.rb @@ -80,7 +80,7 @@ module QA # Retry the attempt to click :commit_button just in case part of the # animation is still in process even when the buttons have the # expected visibility. - commit_success_msg_shown = with_retry do + commit_success_msg_shown = retry_until do click_element :commit_button wait(reload: false) do diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb index ffe8633dd16..523d92c7ef3 100644 --- a/qa/qa/resource/base.rb +++ b/qa/qa/resource/base.rb @@ -27,6 +27,10 @@ module QA attributes.each(&method(:public_send)) end + def wait(max: 60, interval: 0.1) + QA::Support::Waiter.wait(max: max, interval: interval) + end + private def populate_attribute(name, block) diff --git a/qa/qa/resource/events/base.rb b/qa/qa/resource/events/base.rb new file mode 100644 index 00000000000..b50b620b143 --- /dev/null +++ b/qa/qa/resource/events/base.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module QA + module Resource + module Events + MAX_WAIT = 10 + + EventNotFoundError = Class.new(RuntimeError) + + module Base + def events(action: nil) + path = [api_get_events] + path << "?action=#{CGI.escape(action)}" if action + parse_body(api_get_from("#{path.join}")) + end + + private + + def api_get_events + "#{api_get_path}/events" + end + + def wait_for_event + event_found = QA::Support::Waiter.wait(max: max_wait) do + yield + end + + raise EventNotFoundError, "Timed out waiting for event" unless event_found + end + + def max_wait + MAX_WAIT + end + end + end + end +end diff --git a/qa/qa/resource/events/project.rb b/qa/qa/resource/events/project.rb new file mode 100644 index 00000000000..99c78254f42 --- /dev/null +++ b/qa/qa/resource/events/project.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module QA + module Resource + module Events + module Project + include Events::Base + + def wait_for_push(commit_message) + QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push with commit message "#{commit_message}"]) + wait_for_event do + events(action: 'pushed').any? { |event| event.dig(:push_data, :commit_title) == commit_message } + end + end + + def wait_for_push_new_branch(branch_name = "master") + QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push_new_branch with branch_name "#{branch_name}"]) + wait_for_event do + events(action: 'pushed').any? { |event| event.dig(:push_data, :ref) == branch_name } + end + end + end + end + end +end diff --git a/qa/qa/resource/fork.rb b/qa/qa/resource/fork.rb index c6243ff43fa..03bc1f0820b 100644 --- a/qa/qa/resource/fork.rb +++ b/qa/qa/resource/fork.rb @@ -5,12 +5,12 @@ module QA class Fork < Base attribute :project do Resource::Project.fabricate! do |resource| - resource.name = push.project.name - resource.path_with_namespace = "#{user.name}/#{push.project.name}" + resource.name = upstream.project.name + resource.path_with_namespace = "#{user.name}/#{upstream.project.name}" end end - attribute :push do + attribute :upstream do Repository::ProjectPush.fabricate! end @@ -24,7 +24,7 @@ module QA end def fabricate! - populate(:push, :user) + populate(:upstream, :user) # Sign out as admin and sign is as the fork user Page::Main::Menu.perform(&:sign_out) @@ -33,7 +33,7 @@ module QA login.sign_in_using_credentials(user) end - push.project.visit! + upstream.project.visit! Page::Project::Show.perform(&:fork_project) diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb index a7a6f931e28..d7f9ec6a836 100644 --- a/qa/qa/resource/group.rb +++ b/qa/qa/resource/group.rb @@ -33,7 +33,7 @@ module QA end # Ensure that the group was actually created - group_show.wait(time: 1) do + group_show.wait(interval: 1) do group_show.has_text?(path) && group_show.has_new_project_or_subgroup_dropdown? end diff --git a/qa/qa/resource/kubernetes_cluster.rb b/qa/qa/resource/kubernetes_cluster.rb index 986b31da528..93a06be6818 100644 --- a/qa/qa/resource/kubernetes_cluster.rb +++ b/qa/qa/resource/kubernetes_cluster.rb @@ -12,10 +12,6 @@ module QA Page::Project::Operations::Kubernetes::Show.perform(&:ingress_ip) end - attribute :domain do - "#{ingress_ip}.nip.io" - end - def fabricate! @project.visit! @@ -53,6 +49,12 @@ module QA page.await_installed(:ingress) if @install_ingress page.await_installed(:prometheus) if @install_prometheus page.await_installed(:runner) if @install_runner + + if @install_ingress + populate(:ingress_ip) + page.set_domain("#{ingress_ip}.nip.io") + page.save_domain + end end end end diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb index 7150098a00a..45cb317e0eb 100644 --- a/qa/qa/resource/merge_request.rb +++ b/qa/qa/resource/merge_request.rb @@ -58,10 +58,7 @@ module QA populate(:target, :source) project.visit! - Page::Project::Show.perform do |project| - project.wait_for_push - project.new_merge_request - end + Page::Project::Show.perform(&:new_merge_request) Page::MergeRequest::New.perform do |page| page.fill_title(@title) page.fill_description(@description) diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb index 433e5a8f7c9..de1e9f04c36 100644 --- a/qa/qa/resource/project.rb +++ b/qa/qa/resource/project.rb @@ -5,6 +5,8 @@ require 'securerandom' module QA module Resource class Project < Base + include Events::Project + attribute :name attribute :description diff --git a/qa/qa/resource/repository/project_push.rb b/qa/qa/resource/repository/project_push.rb index f4692c3dd4d..cad89ebb0bb 100644 --- a/qa/qa/resource/repository/project_push.rb +++ b/qa/qa/resource/repository/project_push.rb @@ -4,6 +4,8 @@ module QA module Resource module Repository class ProjectPush < Repository::Push + attr_writer :wait_for_push + attribute :project do Project.fabricate! do |resource| resource.name = 'project-with-code' @@ -17,6 +19,7 @@ module QA @commit_message = "This is a test commit" @branch_name = 'master' @new_branch = true + @wait_for_push = true end def repository_http_uri @@ -30,6 +33,7 @@ module QA def fabricate! super project.visit! + project.wait_for_push @commit_message if @wait_for_push end end end diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb index 0bcf5e693f0..0b805b855ac 100644 --- a/qa/qa/runtime/browser.rb +++ b/qa/qa/runtime/browser.rb @@ -8,6 +8,8 @@ module QA class Browser include QA::Scenario::Actable + NotRespondingError = Class.new(RuntimeError) + def initialize self.class.configure! end 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 2fb8402edd8..6632c2977ef 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 @@ -1,8 +1,7 @@ # frozen_string_literal: true module QA - # Failure issue: https://gitlab.com/gitlab-org/quality/nightly/issues/72 - context 'Manage', :smoke, :quarantine do + context 'Manage', :smoke do describe 'Project creation' do it 'user creates a new project' do Runtime::Browser.visit(:gitlab, Page::Main::Login) 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 545da0a8b85..60836a7b98d 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 @@ -26,7 +26,6 @@ module QA push.file_content = "Test with unicode characters ❤✓€❄" end - Page::Project::Show.perform(&:wait_for_push) merge_request.visit! expect(page).to have_text('to be squashed') @@ -38,9 +37,7 @@ module QA merge_request.project.visit! Git::Repository.perform do |repository| - repository.uri = Page::Project::Show.act do - repository_clone_http_location.uri - end + repository.uri = merge_request.project.repository_http_location.uri repository.use_default_credentials 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 3567ddca1a1..8e181eb28c6 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 @@ -23,7 +23,6 @@ module QA proj.name = 'project-qa-test' proj.description = 'project for qa test' end - project.visit! Git::Repository.perform do |repository| repository.uri = project.repository_http_location.uri @@ -53,7 +52,8 @@ module QA push_changes(third_branch) end end - Page::Project::Show.perform(&:wait_for_push) + project.wait_for_push commit_message_of_third_branch + project.visit! end it 'branches are correctly listed after CRUD operations' do diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb index 571cae4a3c5..f2584f55a60 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb @@ -3,22 +3,18 @@ module QA context 'Create' do describe 'Git clone over HTTP', :ldap_no_tls do - let(:location) do - Page::Project::Show.perform(&:repository_clone_http_location).uri - end - - before do + before(:all) do Runtime::Browser.visit(:gitlab, Page::Main::Login) Page::Main::Login.perform(&:sign_in_using_credentials) - project = Resource::Project.fabricate! do |scenario| + @project = Resource::Project.fabricate! do |scenario| scenario.name = 'project-with-code' scenario.description = 'project for git clone tests' end - project.visit! + @project.visit! Git::Repository.perform do |repository| - repository.uri = location + repository.uri = @project.repository_http_location.uri repository.use_default_credentials repository.act do @@ -29,12 +25,12 @@ module QA push_changes end end - Page::Project::Show.perform(&:wait_for_push) + @project.wait_for_push_new_branch end it 'user performs a deep clone' do Git::Repository.perform do |repository| - repository.uri = location + repository.uri = @project.repository_http_location.uri repository.use_default_credentials repository.clone @@ -45,7 +41,7 @@ module QA it 'user performs a shallow clone' do Git::Repository.perform do |repository| - repository.uri = location + repository.uri = @project.repository_http_location.uri repository.use_default_credentials repository.shallow_clone 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 43894372cf5..d1535d6519d 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 @@ -35,7 +35,7 @@ module QA end project.visit! - Page::Project::Show.perform(&:wait_for_push) + project.wait_for_push_new_branch # Check that the push worked expect(page).to have_content(file_name) 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 135925c007f..48800cc81e5 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 @@ -70,7 +70,7 @@ module QA end project.visit! - Page::Project::Show.perform(&:wait_for_push) + project.wait_for_push_new_branch # Check that the push worked expect(page).to have_content(file_name) 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 73f020e7d05..1f4fb08accc 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 @@ -23,10 +23,7 @@ module QA push.project.visit! - Page::Project::Show.perform do |page| - page.wait_for_push - page.wait_for_viewers_to_load - end + Page::Project::Show.perform(&:wait_for_viewers_to_load) expect(page).to have_content('README.md') expect(page).to have_content('This is a test project') diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb index 9d31a25ab35..2e4915b898d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb @@ -20,8 +20,6 @@ module QA end source_project_push.project.visit! - Page::Project::Show.perform(&:wait_for_push) - Page::Project::Menu.perform(&:click_repository_settings) Page::Project::Settings::Repository.perform do |settings| settings.expand_mirroring_repositories do |mirror_settings| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb index 23ea55c2e61..7d96da32423 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb @@ -31,7 +31,7 @@ module QA set_file_size_limit(5) expect(page).to have_content("Application settings saved successfully") - push = push_new_file('oversize_file_1.bin') + push = push_new_file('oversize_file_1.bin', wait_for_push: true) expect(push.output).not_to have_content 'remote: fatal: pack exceeds maximum allowed size' end @@ -39,7 +39,7 @@ module QA set_file_size_limit(1) expect(page).to have_content("Application settings saved successfully") - push = push_new_file('oversize_file_2.bin') + push = push_new_file('oversize_file_2.bin', wait_for_push: false) expect(push.output).to have_content 'remote: fatal: pack exceeds maximum allowed size' end @@ -55,7 +55,7 @@ module QA end end - def push_new_file(file_name) + def push_new_file(file_name, wait_for_push: true) @project.visit! Resource::Repository::ProjectPush.fabricate! do |p| @@ -63,6 +63,7 @@ module QA p.file_name = file_name p.file_content = SecureRandom.random_bytes(2000000) p.commit_message = 'Adding a new file' + p.wait_for_push = wait_for_push end end end 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 d10ad896b3b..58e6c160a3a 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 @@ -5,7 +5,7 @@ module QA 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.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) project_push = Resource::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' @@ -13,7 +13,6 @@ module QA push.commit_message = 'Add README.md' end project_push.project.visit! - Page::Project::Show.act { wait_for_push } expect(page).to have_content('README.md') expect(page).to have_content('This is a test project') diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb index 73a3dc14a65..4464fb812b7 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb @@ -63,6 +63,7 @@ module QA resource.commit_message = 'Add new_file.md' resource.branch_name = branch_name resource.new_branch = false + resource.wait_for_push = false end end end 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 509a639c130..7223831d96f 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 @@ -10,7 +10,7 @@ module QA it 'user adds an ssh key and pushes code to the repository' do Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) key = Resource::SSHKey.fabricate! do |resource| resource.title = key_title @@ -24,13 +24,12 @@ module QA end project_push.project.visit! - Page::Project::Show.act { wait_for_push } expect(page).to have_content('README.md') expect(page).to have_content('Test Use SSH Key') - Page::Main::Menu.act { go_to_profile_settings } - Page::Profile::Menu.act { click_ssh_keys } + Page::Main::Menu.perform(&:go_to_profile_settings) + Page::Profile::Menu.perform(&:click_ssh_keys) Page::Profile::SSHKeys.perform do |ssh_keys| ssh_keys.remove_key(key_title) 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 25cbe41c684..2238d6c382e 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 @@ -11,7 +11,7 @@ module QA it 'users creates a pipeline which gets processed' do Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) project = Resource::Project.fabricate! do |project| project.name = 'project-with-pipelines' @@ -60,11 +60,9 @@ module QA EOF end - Page::Project::Show.act { wait_for_push } - expect(page).to have_content('Add .gitlab-ci.yml') - Page::Project::Menu.act { click_ci_cd_pipelines } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) expect(page).to have_content('All 1') expect(page).to have_content('Add .gitlab-ci.yml') @@ -72,7 +70,7 @@ module QA puts 'Waiting for the runner to process the pipeline' sleep 15 # Runner should process all jobs within 15 seconds. - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) Page::Project::Pipeline::Show.perform do |pipeline| expect(pipeline).to be_running 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 97d36095a69..3f65eabc756 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 @@ -8,7 +8,7 @@ module QA describe 'Git clone using a deploy key' do def login Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) end before(:all) do @@ -29,7 +29,7 @@ module QA resource.image = 'gitlab/gitlab-runner:ubuntu' end - Page::Main::Menu.act { sign_out } + Page::Main::Menu.perform(&:sign_out) end after(:all) do @@ -90,13 +90,12 @@ module QA sha1sum = Digest::SHA1.hexdigest(gitlab_ci) - Page::Project::Show.act { wait_for_push } - Page::Project::Menu.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } - Page::Project::Pipeline::Show.act { go_to_first_job } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) + Page::Project::Pipeline::Show.perform(&:go_to_first_job) Page::Project::Job::Show.perform do |job| - expect(job).to be_successful, "Job status did not become \"passed\"." + expect(job).to be_successful expect(job.output).to include(sha1sum) end end 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 5c8ec465143..8b165a04382 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 @@ -8,7 +8,7 @@ module QA describe 'Auto DevOps support' do def login Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_credentials } + Page::Main::Login.perform(&:sign_in_using_credentials) end [true, false].each do |rbac| @@ -38,11 +38,9 @@ module QA push.commit_message = 'Create Auto DevOps compatible rack application' end - Page::Project::Show.act { wait_for_push } - # Create and connect K8s cluster @cluster = Service::KubernetesCluster.new(rbac: rbac).create! - kubernetes_cluster = Resource::KubernetesCluster.fabricate! do |cluster| + Resource::KubernetesCluster.fabricate! do |cluster| cluster.project = @project cluster.cluster = @cluster cluster.install_helm_tiller = true @@ -51,14 +49,11 @@ module QA cluster.install_runner = true end - kubernetes_cluster.populate(:ingress_ip) @project.visit! - Page::Project::Menu.act { click_ci_cd_settings } + Page::Project::Menu.perform(&:click_ci_cd_settings) Page::Project::Settings::CICD.perform do |p| p.enable_auto_devops end - - kubernetes_cluster.populate(:domain) end after(:all) do @@ -71,14 +66,14 @@ module QA it 'runs auto devops' do @project.visit! - Page::Project::Menu.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) Page::Project::Pipeline::Show.perform do |pipeline| pipeline.go_to_job('build') end Page::Project::Job::Show.perform do |job| - expect(job).to be_sucessful(timeout: 600), "Job did not pass" + expect(job).to be_successful(timeout: 600) job.click_element(:pipeline_path) end @@ -87,7 +82,7 @@ module QA pipeline.go_to_job('test') end Page::Project::Job::Show.perform do |job| - expect(job).to be_sucessful(timeout: 600), "Job did not pass" + expect(job).to be_successful(timeout: 600) job.click_element(:pipeline_path) end @@ -96,12 +91,12 @@ module QA pipeline.go_to_job('production') end Page::Project::Job::Show.perform do |job| - expect(job).to be_sucessful(timeout: 1200), "Job did not pass" + expect(job).to be_successful(timeout: 1200) job.click_element(:pipeline_path) end - Page::Project::Menu.act { click_operations_environments } + Page::Project::Menu.perform(&:click_operations_environments) Page::Project::Operations::Environments::Index.perform do |index| index.go_to_environment('production') end @@ -132,14 +127,14 @@ module QA end @project.visit! - Page::Project::Menu.act { click_ci_cd_pipelines } - Page::Project::Pipeline::Index.act { go_to_latest_pipeline } + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline) Page::Project::Pipeline::Show.perform do |pipeline| pipeline.go_to_job('build') end Page::Project::Job::Show.perform do |job| - expect(job).to be_sucessful(timeout: 600), "Job did not pass" + expect(job).to be_successful(timeout: 600) job.click_element(:pipeline_path) end @@ -148,7 +143,7 @@ module QA pipeline.go_to_job('test') end Page::Project::Job::Show.perform do |job| - expect(job).to be_sucessful(timeout: 600), "Job did not pass" + expect(job).to be_successful(timeout: 600) job.click_element(:pipeline_path) end @@ -157,12 +152,12 @@ module QA pipeline.go_to_job('production') end Page::Project::Job::Show.perform do |job| - expect(job).to be_sucessful(timeout: 1200), "Job did not pass" + expect(job).to be_successful(timeout: 1200) job.click_element(:pipeline_path) end - Page::Project::Menu.act { click_operations_environments } + Page::Project::Menu.perform(&:click_operations_environments) Page::Project::Operations::Environments::Index.perform do |index| index.go_to_environment('production') diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb index f2cd0194b6b..5e97a92a6e3 100644 --- a/qa/qa/support/page/logging.rb +++ b/qa/qa/support/page/logging.rb @@ -10,15 +10,11 @@ module QA super end - def wait(max: 60, time: 0.1, reload: true) - log("with wait: max #{max}; time #{time}; reload #{reload}") - now = Time.now - - element = super + def wait(max: 60, interval: 0.1, reload: true) + log("next wait uses reload: #{reload}") + # Logging of wait start/end/duration is handled by QA::Support::Waiter - log("ended wait after #{Time.now - now} seconds") - - element + super end def scroll_to(selector, text: nil) diff --git a/qa/qa/support/retrier.rb b/qa/qa/support/retrier.rb new file mode 100644 index 00000000000..8be4e9f5365 --- /dev/null +++ b/qa/qa/support/retrier.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module QA + module Support + module Retrier + module_function + + def retry_on_exception(max_attempts: 3, reload_page: nil, sleep_interval: 0.5) + QA::Runtime::Logger.debug("with retry_on_exception: max_attempts #{max_attempts}; sleep_interval #{sleep_interval}") + + attempts = 0 + + begin + QA::Runtime::Logger.debug("Attempt number #{attempts + 1}") + yield + rescue StandardError, RSpec::Expectations::ExpectationNotMetError + sleep sleep_interval + reload_page.refresh if reload_page + attempts += 1 + + retry if attempts < max_attempts + QA::Runtime::Logger.debug("Raising exception after #{max_attempts} attempts") + raise + end + end + end + end +end diff --git a/qa/qa/support/waiter.rb b/qa/qa/support/waiter.rb new file mode 100644 index 00000000000..21a399b4a5f --- /dev/null +++ b/qa/qa/support/waiter.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module QA + module Support + module Waiter + module_function + + def wait(max: 60, interval: 0.1) + QA::Runtime::Logger.debug("with wait: max #{max}; interval #{interval}") + start = Time.now + + while Time.now - start < max + result = yield + if result + log_end(Time.now - start) + return result + end + + sleep(interval) + end + log_end(Time.now - start) + + false + end + + def self.log_end(duration) + QA::Runtime::Logger.debug("ended wait after #{duration} seconds") + end + end + end +end |