diff options
Diffstat (limited to 'qa/qa/page')
25 files changed, 389 insertions, 118 deletions
diff --git a/qa/qa/page/admin/settings/main.rb b/qa/qa/page/admin/settings/main.rb index e7c1220c967..db3387b4557 100644 --- a/qa/qa/page/admin/settings/main.rb +++ b/qa/qa/page/admin/settings/main.rb @@ -6,11 +6,11 @@ module QA include QA::Page::Settings::Common view 'app/views/admin/application_settings/show.html.haml' do - element :advanced_settings_section, 'Repository storage' + element :repository_storage_settings end def expand_repository_storage(&block) - expand_section('Repository storage') do + expand_section(:repository_storage_settings) do RepositoryStorage.perform(&block) end end diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index 0a69af88570..30e35bf7abb 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -13,7 +13,7 @@ module QA visit current_url end - def wait(max: 60, time: 1, reload: true) + def wait(max: 60, time: 0.1, reload: true) start = Time.now while Time.now - start < max diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb index 89125bd2e59..3e0eaa392f5 100644 --- a/qa/qa/page/group/show.rb +++ b/qa/qa/page/group/show.rb @@ -28,11 +28,9 @@ module QA def has_subgroup?(name) filter_by_name(name) - wait(reload: false) do - break false if page.has_content?('Sorry, no groups or projects matched your search') + page.has_text?(/#{name}|Sorry, no groups or projects matched your search/, wait: 60) - page.has_link?(name) - end + page.has_text?(name, wait: 0) end def go_to_new_subgroup diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb index 596205fe540..26c99efc53d 100644 --- a/qa/qa/page/main/login.rb +++ b/qa/qa/page/main/login.rb @@ -26,53 +26,58 @@ module QA end def initialize + # The login page is usually the entry point for all the scenarios so + # we need to wait for the instance to start. That said, in some cases + # we are already logged-in so we check both cases here. wait(max: 500) do - page.has_css?('.application') + page.has_css?('.login-page') || + Page::Menu::Main.act { has_personal_area? } end end - def set_initial_password_if_present - if page.has_content?('Change your password') - fill_in :user_password, with: Runtime::User.password - fill_in :user_password_confirmation, with: Runtime::User.password - click_button 'Change your password' + def sign_in_using_credentials + # Don't try to log-in if we're already logged-in + return if Page::Menu::Main.act { has_personal_area? } + + using_wait_time 0 do + set_initial_password_if_present + + if Runtime::User.ldap_user? + sign_in_using_ldap_credentials + else + sign_in_using_gitlab_credentials + end end end - def sign_in_using_credentials - if Runtime::User.ldap_user? - sign_in_using_ldap_credentials - else - sign_in_using_gitlab_credentials - end + def self.path + '/users/sign_in' end - def sign_in_using_ldap_credentials - using_wait_time 0 do - set_initial_password_if_present + private - click_link 'LDAP' + def sign_in_using_ldap_credentials + click_link 'LDAP' - fill_in :username, with: Runtime::User.ldap_username - fill_in :password, with: Runtime::User.ldap_password - click_button 'Sign in' - end + fill_in :username, with: Runtime::User.ldap_username + fill_in :password, with: Runtime::User.ldap_password + click_button 'Sign in' end def sign_in_using_gitlab_credentials - using_wait_time 0 do - set_initial_password_if_present - - click_link 'Standard' if page.has_content?('LDAP') + click_link 'Standard' if page.has_content?('LDAP') - fill_in :user_login, with: Runtime::User.name - fill_in :user_password, with: Runtime::User.password - click_button 'Sign in' - end + fill_in :user_login, with: Runtime::User.name + fill_in :user_password, with: Runtime::User.password + click_button 'Sign in' end - def self.path - '/users/sign_in' + def set_initial_password_if_present + return unless page.has_content?('Change your password') + + fill_in :user_password, with: Runtime::User.password + fill_in :user_password_confirmation, with: Runtime::User.password + click_button 'Change your password' end end end diff --git a/qa/qa/page/menu/main.rb b/qa/qa/page/menu/main.rb index 644fedecc90..fda9c45c091 100644 --- a/qa/qa/page/menu/main.rb +++ b/qa/qa/page/menu/main.rb @@ -55,7 +55,8 @@ module QA end def has_personal_area? - page.has_selector?('.qa-user-avatar') + # No need to wait, either we're logged-in, or not. + using_wait_time(0) { page.has_selector?('.qa-user-avatar') } end private diff --git a/qa/qa/page/menu/side.rb b/qa/qa/page/menu/side.rb index 7e028add2ef..6bf4825cf00 100644 --- a/qa/qa/page/menu/side.rb +++ b/qa/qa/page/menu/side.rb @@ -7,10 +7,13 @@ module QA element :settings_link, 'link_to edit_project_path' element :repository_link, "title: 'Repository'" element :pipelines_settings_link, "title: 'CI / CD'" + element :operations_kubernetes_link, "title: _('Kubernetes')" element :issues_link, /link_to.*shortcuts-issues/ element :issues_link_text, "Issues" element :top_level_items, '.sidebar-top-level-items' + element :operations_section, "class: 'shortcuts-operations'" element :activity_link, "title: 'Activity'" + element :wiki_link_text, "Wiki" end view 'app/assets/javascripts/fly_out_nav.js' do @@ -33,6 +36,14 @@ module QA end end + def click_operations_kubernetes + hover_operations do + within_submenu do + click_link('Kubernetes') + end + end + end + def click_ci_cd_pipelines within_sidebar do click_link('CI / CD') @@ -51,6 +62,12 @@ module QA end end + def click_wiki + within_sidebar do + click_link('Wiki') + end + end + private def hover_settings @@ -61,6 +78,14 @@ module QA end end + def hover_operations + within_sidebar do + find('.shortcuts-operations').hover + + yield + end + end + def within_sidebar page.within('.sidebar-top-level-items') do yield diff --git a/qa/qa/page/project/job/show.rb b/qa/qa/page/project/job/show.rb index 83bb224b5c3..228ffd9d381 100644 --- a/qa/qa/page/project/job/show.rb +++ b/qa/qa/page/project/job/show.rb @@ -4,8 +4,9 @@ module QA::Page COMPLETED_STATUSES = %w[passed failed canceled blocked skipped manual].freeze # excludes created, pending, running PASSED_STATUS = 'passed'.freeze - view 'app/views/projects/jobs/show.html.haml' do + view 'app/views/shared/builds/_build_output.html.haml' do element :build_output, '.js-build-output' + element :loading_animation, '.js-build-refresh' end view 'app/assets/javascripts/vue_shared/components/ci_badge_link.vue' do @@ -20,6 +21,10 @@ module QA::Page find('.ci-status').text == PASSED_STATUS end + def trace_loading? + has_css?('.js-build-refresh') + end + # Reminder: You may wish to wait for a particular job status before checking output def output find('.js-build-output').text diff --git a/qa/qa/page/project/operations/kubernetes/add.rb b/qa/qa/page/project/operations/kubernetes/add.rb new file mode 100644 index 00000000000..9b3c482fa6c --- /dev/null +++ b/qa/qa/page/project/operations/kubernetes/add.rb @@ -0,0 +1,19 @@ +module QA + module Page + module Project + module Operations + module Kubernetes + class Add < Page::Base + view 'app/views/projects/clusters/new.html.haml' do + element :add_kubernetes_cluster_button, "link_to s_('ClusterIntegration|Add an existing Kubernetes cluster')" + end + + def add_existing_cluster + click_on 'Add an existing Kubernetes cluster' + end + end + end + end + end + end +end diff --git a/qa/qa/page/project/operations/kubernetes/add_existing.rb b/qa/qa/page/project/operations/kubernetes/add_existing.rb new file mode 100644 index 00000000000..eef82b5f329 --- /dev/null +++ b/qa/qa/page/project/operations/kubernetes/add_existing.rb @@ -0,0 +1,39 @@ +module QA + module Page + module Project + module Operations + module Kubernetes + class AddExisting < Page::Base + view 'app/views/projects/clusters/user/_form.html.haml' do + element :cluster_name, 'text_field :name' + element :api_url, 'text_field :api_url' + element :ca_certificate, 'text_area :ca_cert' + element :token, 'text_field :token' + element :add_cluster_button, "submit s_('ClusterIntegration|Add Kubernetes cluster')" + end + + def set_cluster_name(name) + fill_in 'cluster_name', with: name + end + + def set_api_url(api_url) + fill_in 'cluster_platform_kubernetes_attributes_api_url', with: api_url + end + + def set_ca_certificate(ca_certificate) + fill_in 'cluster_platform_kubernetes_attributes_ca_cert', with: ca_certificate + end + + def set_token(token) + fill_in 'cluster_platform_kubernetes_attributes_token', with: token + end + + def add_cluster! + click_on 'Add Kubernetes cluster' + end + end + end + end + end + end +end diff --git a/qa/qa/page/project/operations/kubernetes/index.rb b/qa/qa/page/project/operations/kubernetes/index.rb new file mode 100644 index 00000000000..7261b5645da --- /dev/null +++ b/qa/qa/page/project/operations/kubernetes/index.rb @@ -0,0 +1,19 @@ +module QA + module Page + module Project + module Operations + module Kubernetes + class Index < Page::Base + view 'app/views/projects/clusters/_empty_state.html.haml' do + element :add_kubernetes_cluster_button, "link_to s_('ClusterIntegration|Add Kubernetes cluster')" + end + + def add_kubernetes_cluster + click_on 'Add Kubernetes cluster' + end + end + end + end + end + end +end diff --git a/qa/qa/page/project/operations/kubernetes/show.rb b/qa/qa/page/project/operations/kubernetes/show.rb new file mode 100644 index 00000000000..4923304133e --- /dev/null +++ b/qa/qa/page/project/operations/kubernetes/show.rb @@ -0,0 +1,39 @@ +module QA + module Page + module Project + module Operations + module Kubernetes + class Show < Page::Base + view 'app/assets/javascripts/clusters/components/application_row.vue' do + element :application_row, 'js-cluster-application-row-${this.id}' + element :install_button, "s__('ClusterIntegration|Install')" + element :installed_button, "s__('ClusterIntegration|Installed')" + end + + view 'app/assets/javascripts/clusters/components/applications.vue' do + element :ingress_ip_address, 'id="ingress-ip-address"' + end + + def install!(application_name) + within(".js-cluster-application-row-#{application_name}") do + click_on 'Install' + end + end + + def await_installed(application_name) + within(".js-cluster-application-row-#{application_name}") do + page.has_text?('Installed', wait: 300) + end + end + + def ingress_ip + # We need to wait longer since it can take some time before the + # ip address is assigned for the ingress controller + page.find('#ingress-ip-address', wait: 500).value + end + end + end + end + end + end +end diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb index ec61c47b3bb..babc0079f3f 100644 --- a/qa/qa/page/project/pipeline/show.rb +++ b/qa/qa/page/project/pipeline/show.rb @@ -24,10 +24,10 @@ module QA::Page end end - def has_build?(name, status: :success) + def has_build?(name, status: :success, wait: nil) within('.pipeline-graph') do within('.ci-job-component', text: name) do - has_selector?(".ci-status-icon-#{status}") + has_selector?(".ci-status-icon-#{status}", { wait: wait }.compact) end end end diff --git a/qa/qa/page/project/settings/advanced.rb b/qa/qa/page/project/settings/advanced.rb index 5ef00504fdf..d7b2b66b587 100644 --- a/qa/qa/page/project/settings/advanced.rb +++ b/qa/qa/page/project/settings/advanced.rb @@ -4,9 +4,9 @@ module QA module Settings class Advanced < Page::Base view 'app/views/projects/edit.html.haml' do - element :project_path_field, 'f.text_field :path' - element :project_name_field, 'f.text_field :name' - element :rename_project_button, "f.submit 'Rename project'" + element :project_path_field, 'text_field :path' + element :project_name_field, 'text_field :name' + element :rename_project_button, "submit 'Rename project'" end def rename_to(path) diff --git a/qa/qa/page/project/settings/ci_cd.rb b/qa/qa/page/project/settings/ci_cd.rb index 145c3d3ddfa..0f739f61db9 100644 --- a/qa/qa/page/project/settings/ci_cd.rb +++ b/qa/qa/page/project/settings/ci_cd.rb @@ -6,21 +6,38 @@ module QA # rubocop:disable Naming/FileName include Common view 'app/views/projects/settings/ci_cd/show.html.haml' do - element :runners_settings, 'Runners settings' - element :secret_variables, 'Variables' + element :autodevops_settings + element :runners_settings + element :variables_settings + end + + view 'app/views/projects/settings/ci_cd/_autodevops_form.html.haml' do + element :enable_auto_devops_field, 'radio_button :enabled' + element :domain_field, 'text_field :domain' + element :enable_auto_devops_button, "%strong= s_('CICD|Enable Auto DevOps')" + element :domain_input, "%strong= _('Domain')" + element :save_changes_button, "submit _('Save changes')" end def expand_runners_settings(&block) - expand_section('Runners settings') do + expand_section(:runners_settings) do Settings::Runners.perform(&block) end end def expand_secret_variables(&block) - expand_section('Variables') do + expand_section(:variables_settings) do Settings::SecretVariables.perform(&block) end end + + def enable_auto_devops_with_domain(domain) + expand_section(:autodevops_settings) do + choose 'Enable Auto DevOps' + fill_in 'Domain', with: domain + click_on 'Save changes' + end + end end end end diff --git a/qa/qa/page/project/settings/deploy_keys.rb b/qa/qa/page/project/settings/deploy_keys.rb index 4428e263bbb..a8558d7c50a 100644 --- a/qa/qa/page/project/settings/deploy_keys.rb +++ b/qa/qa/page/project/settings/deploy_keys.rb @@ -57,6 +57,10 @@ module QA private def within_project_deploy_keys + wait(reload: false) do + find_element(:project_deploy_keys) + end + within_element(:project_deploy_keys) do yield end diff --git a/qa/qa/page/project/settings/main.rb b/qa/qa/page/project/settings/main.rb index 5d743f4c9c8..d8cf1d49dd2 100644 --- a/qa/qa/page/project/settings/main.rb +++ b/qa/qa/page/project/settings/main.rb @@ -6,11 +6,11 @@ module QA include Common view 'app/views/projects/edit.html.haml' do - element :advanced_settings_section, 'Advanced settings' + element :advanced_settings end def expand_advanced_settings(&block) - expand_section('Advanced settings') do + expand_section(:advanced_settings) do Advanced.perform(&block) end end diff --git a/qa/qa/page/project/settings/merge_request.rb b/qa/qa/page/project/settings/merge_request.rb index a88cd661016..d044d3715a9 100644 --- a/qa/qa/page/project/settings/merge_request.rb +++ b/qa/qa/page/project/settings/merge_request.rb @@ -5,17 +5,17 @@ module QA class MergeRequest < QA::Page::Base include Common - view 'app/views/projects/_merge_request_merge_method_settings.html.haml' do - element :radio_button_merge_ff - end - view 'app/views/projects/edit.html.haml' do - element :merge_request_settings, 'Merge request settings' + element :merge_request_settings element :save_merge_request_changes end + view 'app/views/projects/_merge_request_merge_method_settings.html.haml' do + element :radio_button_merge_ff + end + def enable_ff_only - expand_section('Merge request settings') do + expand_section(:merge_request_settings) do click_element :radio_button_merge_ff click_element :save_merge_request_changes end diff --git a/qa/qa/page/project/settings/protected_branches.rb b/qa/qa/page/project/settings/protected_branches.rb index 63bc3aaa2bc..0bd031e96b5 100644 --- a/qa/qa/page/project/settings/protected_branches.rb +++ b/qa/qa/page/project/settings/protected_branches.rb @@ -40,16 +40,16 @@ module QA click_allow(:push, 'No one') end - def allow_devs_and_masters_to_push - click_allow(:push, 'Developers + Masters') + def allow_devs_and_maintainers_to_push + click_allow(:push, 'Developers + Maintainers') end def allow_no_one_to_merge click_allow(:merge, 'No one') end - def allow_devs_and_masters_to_merge - click_allow(:merge, 'Developers + Masters') + def allow_devs_and_maintainers_to_merge + click_allow(:merge, 'Developers + Maintainers') end def protect_branch @@ -75,10 +75,6 @@ module QA within_element(:"allowed_to_#{action}_dropdown") do click_on text - - wait(reload: false) do - has_css?('.is-active') - end end end end diff --git a/qa/qa/page/project/settings/repository.rb b/qa/qa/page/project/settings/repository.rb index 30900e74e90..1ed5f455a85 100644 --- a/qa/qa/page/project/settings/repository.rb +++ b/qa/qa/page/project/settings/repository.rb @@ -6,17 +6,21 @@ module QA include Common view 'app/views/projects/deploy_keys/_index.html.haml' do - element :deploy_keys_section, 'Deploy Keys' + element :deploy_keys_settings + end + + view 'app/views/projects/protected_branches/shared/_index.html.haml' do + element :protected_branches_settings end def expand_deploy_keys(&block) - expand_section('Deploy Keys') do + expand_section(:deploy_keys_settings) do DeployKeys.perform(&block) end end def expand_protected_branches(&block) - expand_section('Protected Branches') do + expand_section(:protected_branches_settings) do ProtectedBranches.perform(&block) end end diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb index 5bbef040330..1406edece17 100644 --- a/qa/qa/page/project/show.rb +++ b/qa/qa/page/project/show.rb @@ -2,11 +2,7 @@ module QA module Page module Project class Show < Page::Base - view 'app/views/shared/_clone_panel.html.haml' do - element :clone_dropdown - element :clone_options_dropdown, '.clone-options-dropdown' - element :project_repository_location, 'text_field_tag :project_clone' - end + include Page::Shared::ClonePanel view 'app/views/projects/_last_push.html.haml' do element :create_merge_request @@ -26,21 +22,6 @@ module QA element :branches_dropdown end - def choose_repository_clone_http - choose_repository_clone('HTTP', 'http') - end - - def choose_repository_clone_ssh - # It's not always beginning with ssh:// so detecting with @ - # would be more reliable because ssh would always contain it. - # We can't use .git because HTTP also contain that part. - choose_repository_clone('SSH', '@') - end - - def repository_location - Git::Location.new(find('#project_clone').value) - end - def project_name find('.qa-project-name').text end @@ -65,31 +46,11 @@ module QA click_element :create_merge_request end - def wait_for_push - sleep 5 - refresh - end - def go_to_new_issue click_element :new_menu_toggle click_link 'New issue' end - - private - - def choose_repository_clone(kind, detect_text) - wait(reload: false) do - click_element :clone_dropdown - - page.within('.clone-options-dropdown') do - click_link(kind) - end - - # Ensure git clone textbox was updated - repository_location.git_uri.include?(detect_text) - end - end end end end diff --git a/qa/qa/page/project/wiki/edit.rb b/qa/qa/page/project/wiki/edit.rb new file mode 100644 index 00000000000..6fa45569cc0 --- /dev/null +++ b/qa/qa/page/project/wiki/edit.rb @@ -0,0 +1,27 @@ +module QA + module Page + module Project + module Wiki + class Edit < Page::Base + view 'app/views/projects/wikis/_main_links.html.haml' do + element :new_page_link, 'New page' + element :page_history_link, 'Page history' + element :edit_page_link, 'Edit' + end + + def go_to_new_page + click_on 'New page' + end + + def got_to_view_history_page + click_on 'Page history' + end + + def go_to_edit_page + click_on 'Edit' + end + end + end + end + end +end diff --git a/qa/qa/page/project/wiki/new.rb b/qa/qa/page/project/wiki/new.rb new file mode 100644 index 00000000000..415b3835538 --- /dev/null +++ b/qa/qa/page/project/wiki/new.rb @@ -0,0 +1,45 @@ +module QA + module Page + module Project + module Wiki + class New < Page::Base + view 'app/views/projects/wikis/_form.html.haml' do + element :wiki_title_textbox, 'text_field :title' + element :wiki_content_textarea, "render 'projects/zen', f: f, attr: :content" + element :wiki_message_textbox, 'text_field :message' + element :save_changes_button, 'submit _("Save changes")' + element :create_page_button, 'submit s_("Wiki|Create page")' + end + + view 'app/views/shared/empty_states/_wikis.html.haml' do + element :create_link, 'Create your first page' + end + + def go_to_create_first_page + click_link 'Create your first page' + end + + def set_title(title) + fill_in 'wiki_title', with: title + end + + def set_content(content) + fill_in 'wiki_content', with: content + end + + def set_message(message) + fill_in 'wiki_message', with: message + end + + def save_changes + click_on 'Save changes' + end + + def create_new_page + click_on 'Create page' + end + end + end + end + end +end diff --git a/qa/qa/page/project/wiki/show.rb b/qa/qa/page/project/wiki/show.rb new file mode 100644 index 00000000000..044e514bab3 --- /dev/null +++ b/qa/qa/page/project/wiki/show.rb @@ -0,0 +1,19 @@ +module QA + module Page + module Project + module Wiki + class Show < Page::Base + include Page::Shared::ClonePanel + + view 'app/views/projects/wikis/pages.html.haml' do + element :clone_repository_link, 'Clone repository' + end + + def go_to_clone_repository + click_on 'Clone repository' + end + end + end + end + end +end diff --git a/qa/qa/page/settings/common.rb b/qa/qa/page/settings/common.rb index a683a6829d5..f9f71aa4a72 100644 --- a/qa/qa/page/settings/common.rb +++ b/qa/qa/page/settings/common.rb @@ -4,19 +4,17 @@ module QA module Common # Click the Expand button present in the specified section # - # @param [String] name present in the container in the DOM - def expand_section(name) - page.within('#content-body') do - page.within('section', text: name) do - # Because it is possible to click the button before the JS toggle code is bound - wait(reload: false) do - click_button 'Expand' unless first('button', text: 'Collapse') + # @param [Symbol] and `element` name defined in a `view` block + def expand_section(element_name) + within_element(element_name) do + # Because it is possible to click the button before the JS toggle code is bound + wait(reload: false) do + click_button 'Expand' unless first('button', text: 'Collapse') - page.has_content?('Collapse') - end - - yield if block_given? + page.has_content?('Collapse') end + + yield if block_given? end end end diff --git a/qa/qa/page/shared/clone_panel.rb b/qa/qa/page/shared/clone_panel.rb new file mode 100644 index 00000000000..73e3dff956d --- /dev/null +++ b/qa/qa/page/shared/clone_panel.rb @@ -0,0 +1,50 @@ +module QA + module Page + module Shared + module ClonePanel + def self.included(base) + base.view 'app/views/shared/_clone_panel.html.haml' do + element :clone_dropdown + element :clone_options_dropdown, '.clone-options-dropdown' + element :project_repository_location, 'text_field_tag :project_clone' + end + end + + def choose_repository_clone_http + choose_repository_clone('HTTP', 'http') + end + + def choose_repository_clone_ssh + # It's not always beginning with ssh:// so detecting with @ + # would be more reliable because ssh would always contain it. + # We can't use .git because HTTP also contain that part. + choose_repository_clone('SSH', '@') + end + + def repository_location + Git::Location.new(find('#project_clone').value) + end + + def wait_for_push + sleep 5 + refresh + end + + private + + def choose_repository_clone(kind, detect_text) + wait(reload: false) do + click_element :clone_dropdown + + page.within('.clone-options-dropdown') do + click_link(kind) + end + + # Ensure git clone textbox was updated + repository_location.git_uri.include?(detect_text) + end + end + end + end + end +end |