diff options
Diffstat (limited to 'qa/qa/page')
55 files changed, 822 insertions, 238 deletions
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index 42208f05c89..cb3827f8eb1 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -133,8 +133,13 @@ module QA end # replace with (..., page = self.class) - def click_element(name, page = nil, text: nil, wait: Capybara.default_max_wait_time) - find_element(name, text: text, wait: wait).click + def click_element(name, page = nil, **kwargs) + wait_for_requests + + wait = kwargs.delete(:wait) || Capybara.default_max_wait_time + text = kwargs.delete(:text) + + find(element_selector_css(name, kwargs), text: text, wait: wait).click page.validate_elements_present! if page end diff --git a/qa/qa/page/component/breadcrumbs.rb b/qa/qa/page/component/breadcrumbs.rb index 656aa380bbd..2576e376e4e 100644 --- a/qa/qa/page/component/breadcrumbs.rb +++ b/qa/qa/page/component/breadcrumbs.rb @@ -4,7 +4,11 @@ module QA module Page module Component module Breadcrumbs + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/layouts/nav/_breadcrumbs.html.haml' do element :breadcrumb_links_content end diff --git a/qa/qa/page/component/ci_badge_link.rb b/qa/qa/page/component/ci_badge_link.rb index 3db675c3a60..8629399e911 100644 --- a/qa/qa/page/component/ci_badge_link.rb +++ b/qa/qa/page/component/ci_badge_link.rb @@ -4,6 +4,8 @@ module QA module Page module Component module CiBadgeLink + extend QA::Page::PageConcern + COMPLETED_STATUSES = %w[passed failed canceled blocked skipped manual].freeze # excludes created, pending, running INCOMPLETE_STATUSES = %w[pending created running].freeze @@ -27,6 +29,8 @@ module QA end def self.included(base) + super + base.view 'app/assets/javascripts/vue_shared/components/ci_badge_link.vue' do element :status_badge end diff --git a/qa/qa/page/component/clone_panel.rb b/qa/qa/page/component/clone_panel.rb index fbe19e5802b..a0aea6fe44d 100644 --- a/qa/qa/page/component/clone_panel.rb +++ b/qa/qa/page/component/clone_panel.rb @@ -4,7 +4,11 @@ module QA module Page module Component module ClonePanel + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/projects/buttons/_clone.html.haml' do element :clone_dropdown element :clone_options diff --git a/qa/qa/page/component/confirm_modal.rb b/qa/qa/page/component/confirm_modal.rb index 355e2783fb7..039640d207a 100644 --- a/qa/qa/page/component/confirm_modal.rb +++ b/qa/qa/page/component/confirm_modal.rb @@ -4,7 +4,11 @@ module QA module Page module Component module ConfirmModal + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/shared/_confirm_modal.html.haml' do element :confirm_modal element :confirm_input diff --git a/qa/qa/page/component/custom_metric.rb b/qa/qa/page/component/custom_metric.rb new file mode 100644 index 00000000000..094979f5e18 --- /dev/null +++ b/qa/qa/page/component/custom_metric.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module QA + module Page + module Component + module CustomMetric + extend QA::Page::PageConcern + + def self.included(base) + super + + base.view 'app/assets/javascripts/custom_metrics/components/custom_metrics_form_fields.vue' do + element :custom_metric_prometheus_title_field + element :custom_metric_prometheus_query_field + element :custom_metric_prometheus_y_label_field + element :custom_metric_prometheus_unit_label_field + element :custom_metric_prometheus_legend_label_field + end + end + + def add_custom_metric + fill_element :custom_metric_prometheus_title_field, 'HTTP Requests Total' + fill_element :custom_metric_prometheus_query_field, 'rate(http_requests_total[5m])' + fill_element :custom_metric_prometheus_y_label_field, 'Requests/second' + fill_element :custom_metric_prometheus_unit_label_field, 'req/sec' + fill_element :custom_metric_prometheus_legend_label_field, 'HTTP requests' + + save_changes + end + + def save_changes + click_button(class: 'btn-success') + end + + def delete_custom_metric + click_button(class: 'btn-danger') + within('.modal-content') { click_button(class: 'btn-danger') } + end + + def edit_custom_metric + fill_element :custom_metric_prometheus_title_field, '' + fill_element :custom_metric_prometheus_title_field, 'Throughput' + + save_changes + end + end + end + end +end diff --git a/qa/qa/page/component/design_management.rb b/qa/qa/page/component/design_management.rb new file mode 100644 index 00000000000..a8a24bd3949 --- /dev/null +++ b/qa/qa/page/component/design_management.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +module QA + module Page + module Component + module DesignManagement + extend QA::Page::PageConcern + + def self.included(base) + super + + base.class_eval do + view 'app/assets/javascripts/design_management/components/design_notes/design_discussion.vue' do + element :design_discussion_content + end + + view 'app/assets/javascripts/design_management/components/design_notes/design_note.vue' do + element :note_content + end + + view 'app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue' do + element :note_textarea + element :save_comment_button + end + + view 'app/assets/javascripts/design_management/components/design_overlay.vue' do + element :design_image_button + end + + view 'app/assets/javascripts/design_management/components/list/item.vue' do + element :design_file_name + element :design_image + end + end + end + + def add_annotation(note) + click_element(:design_image_button) + fill_element(:note_textarea, note) + click_element(:save_comment_button) + + # It takes a moment for the annotation to be saved. + # We'll check for the annotation in a test, but here we'll at least + # wait for the "Save comment" button to disappear + saved = has_no_element?(:save_comment_button) + + raise ExpectationNotMet, %q(There was a problem while adding the annotation) unless saved + end + + def add_design(design_file_path) + # `attach_file` doesn't seem able to find element via data attributes. + # It accepts a `class:` option, but that only works for class attributes + # It doesn't work as a CSS selector. + # So instead we use the name attribute as a locator + page.attach_file("design_file", design_file_path, make_visible: { display: 'block' }) + + filename = ::File.basename(design_file_path) + + found = wait_until(reload: false, sleep_interval: 1) do + image = find_element(:design_image) + + has_element?(:design_file_name, text: filename) && + image["complete"] && + image["naturalWidth"].to_i > 0 + end + + raise ElementNotFound, %Q(Attempted to attach design "#{filename}" but it did not appear) unless found + end + + def click_design(filename) + click_element(:design_file_name, text: filename) + end + + def has_annotation?(note) + within_element_by_index(:design_discussion_content, 0) do + has_element?(:note_content, text: note) + end + end + end + end + end +end diff --git a/qa/qa/page/component/groups_filter.rb b/qa/qa/page/component/groups_filter.rb index 7eb1257db71..f82bb81a3fc 100644 --- a/qa/qa/page/component/groups_filter.rb +++ b/qa/qa/page/component/groups_filter.rb @@ -4,7 +4,11 @@ module QA module Page module Component module GroupsFilter + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/shared/groups/_search_form.html.haml' do element :groups_filter end diff --git a/qa/qa/page/component/issuable/common.rb b/qa/qa/page/component/issuable/common.rb index 1155d4da036..bbab1746d7a 100644 --- a/qa/qa/page/component/issuable/common.rb +++ b/qa/qa/page/component/issuable/common.rb @@ -5,7 +5,11 @@ module QA module Component module Issuable module Common + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/assets/javascripts/issue_show/components/title.vue' do element :edit_button element :title, required: true diff --git a/qa/qa/page/component/lazy_loader.rb b/qa/qa/page/component/lazy_loader.rb index 6f74a4691ba..2123431fc55 100644 --- a/qa/qa/page/component/lazy_loader.rb +++ b/qa/qa/page/component/lazy_loader.rb @@ -4,7 +4,11 @@ module QA module Page module Component module LazyLoader + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/assets/javascripts/lazy_loader.js' do element :js_lazy_loaded end diff --git a/qa/qa/page/component/legacy_clone_panel.rb b/qa/qa/page/component/legacy_clone_panel.rb index 7b4b30623a6..ebab9fd708c 100644 --- a/qa/qa/page/component/legacy_clone_panel.rb +++ b/qa/qa/page/component/legacy_clone_panel.rb @@ -4,7 +4,11 @@ module QA module Page module Component module LegacyClonePanel + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/shared/_clone_panel.html.haml' do element :clone_dropdown element :clone_options_dropdown, '.clone-options-dropdown' # rubocop:disable QA/ElementWithPattern diff --git a/qa/qa/page/component/note.rb b/qa/qa/page/component/note.rb index 3e8ed9069ce..0e9cdd49519 100644 --- a/qa/qa/page/component/note.rb +++ b/qa/qa/page/component/note.rb @@ -4,7 +4,11 @@ module QA module Page module Component module Note + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/assets/javascripts/notes/components/comment_form.vue' do element :note_dropdown element :discussion_option diff --git a/qa/qa/page/component/project/templates.rb b/qa/qa/page/component/project/templates.rb new file mode 100644 index 00000000000..8baf15acdff --- /dev/null +++ b/qa/qa/page/component/project/templates.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module QA + module Page::Component + module Project + module Templates + def use_template_for_project(project_name) + within find_element(:template_option_row, text: project_name) do + click_element :use_template_button + end + end + end + end + end +end diff --git a/qa/qa/page/component/select2.rb b/qa/qa/page/component/select2.rb index e667fad1dd3..b8beb64b6bd 100644 --- a/qa/qa/page/component/select2.rb +++ b/qa/qa/page/component/select2.rb @@ -18,10 +18,14 @@ module QA end end - def search_and_select(item_text) + def search_item(item_text) find('.select2-input').set(item_text) wait_for_search_to_complete + end + + def search_and_select(item_text) + search_item(item_text) select_item(item_text) end @@ -36,7 +40,7 @@ module QA end def dropdown_open? - has_css?('.select2-input') + find('.select2-focusser').disabled? end end end diff --git a/qa/qa/page/component/web_ide/alert.rb b/qa/qa/page/component/web_ide/alert.rb index 0f0623d5ebf..c2903662b52 100644 --- a/qa/qa/page/component/web_ide/alert.rb +++ b/qa/qa/page/component/web_ide/alert.rb @@ -5,8 +5,12 @@ module QA module Component module WebIDE module Alert - def self.prepended(page) - page.module_eval do + extend QA::Page::PageConcern + + def self.prepended(base) + super + + base.class_eval do view 'app/assets/javascripts/ide/components/error_message.vue' do element :flash_alert end diff --git a/qa/qa/page/dashboard/snippet/edit.rb b/qa/qa/page/dashboard/snippet/edit.rb new file mode 100644 index 00000000000..d28b8178c99 --- /dev/null +++ b/qa/qa/page/dashboard/snippet/edit.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module QA + module Page + module Dashboard + module Snippet + class Edit < Page::Base + view 'app/views/shared/snippets/_form.html.haml' do + element :submit_button + end + + view 'app/assets/javascripts/snippets/components/edit.vue' do + element :submit_button + end + + def add_to_file_content(content) + finished_loading? + text_area.set content + text_area.has_text?(content) # wait for changes to take effect + end + + def save_changes + click_element(:submit_button) + wait_until { assert_no_element(:submit_button) } + end + + private + + def text_area + find('#editor textarea', visible: false) + end + end + end + end + end +end diff --git a/qa/qa/page/dashboard/snippet/new.rb b/qa/qa/page/dashboard/snippet/new.rb index da5013e787e..d1a194ba1db 100644 --- a/qa/qa/page/dashboard/snippet/new.rb +++ b/qa/qa/page/dashboard/snippet/new.rb @@ -5,16 +5,33 @@ module QA module Dashboard module Snippet class New < Page::Base + view 'app/assets/javascripts/snippets/components/edit.vue' do + element :submit_button + end + + view 'app/assets/javascripts/snippets/components/snippet_description_edit.vue' do + element :snippet_description_field + element :description_placeholder, required: true + end + + view 'app/assets/javascripts/snippets/components/snippet_title.vue' do + element :snippet_title, required: true + end + + view 'app/assets/javascripts/snippets/components/snippet_blob_edit.vue' do + element :snippet_file_name + end + view 'app/views/shared/form_elements/_description.html.haml' do element :issuable_form_description end view 'app/views/shared/snippets/_form.html.haml' do - element :description_field + element :snippet_description_field element :description_placeholder element :snippet_title element :snippet_file_name - element :create_snippet_button + element :submit_button end view 'app/views/projects/_zen.html.haml' do @@ -28,7 +45,7 @@ module QA def fill_description(description) click_element :description_placeholder - fill_element :description_field, description + fill_element :snippet_description_field, description end def set_visibility(visibility) @@ -46,7 +63,8 @@ module QA end def click_create_snippet_button - click_element :create_snippet_button + wait_until(reload: false) { !find_element(:submit_button).disabled? } + click_element :submit_button end private diff --git a/qa/qa/page/dashboard/snippet/show.rb b/qa/qa/page/dashboard/snippet/show.rb index 88d6ef02d22..d43b64cd1d4 100644 --- a/qa/qa/page/dashboard/snippet/show.rb +++ b/qa/qa/page/dashboard/snippet/show.rb @@ -5,10 +5,17 @@ module QA module Dashboard module Snippet class Show < Page::Base + view 'app/assets/javascripts/snippets/components/snippet_description_view.vue' do + element :snippet_description_field + end + + view 'app/assets/javascripts/snippets/components/snippet_title.vue' do + element :snippet_title, required: true + end + view 'app/views/shared/snippets/_header.html.haml' do element :snippet_title, required: true - element :snippet_description, required: true - element :embed_type + element :snippet_description_field, required: true element :snippet_box end @@ -16,22 +23,38 @@ module QA element :file_title_name end + view 'app/assets/javascripts/blob/components/blob_header_filepath.vue' do + element :file_title_name + end + view 'app/views/shared/_file_highlight.html.haml' do element :file_content end + view 'app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue' do + element :file_content + end + + view 'app/assets/javascripts/snippets/components/snippet_header.vue' do + element :snippet_action_button + element :delete_snippet_button + end + + view 'app/assets/javascripts/snippets/components/snippet_blob_view.vue' do + element :clone_button + end + + view 'app/assets/javascripts/vue_shared/components/clone_dropdown.vue' do + element :copy_http_url_button + element :copy_ssh_url_button + end + def has_snippet_title?(snippet_title) has_element? :snippet_title, text: snippet_title end def has_snippet_description?(snippet_description) - has_element? :snippet_description, text: snippet_description - end - - def has_embed_type?(embed_type) - within_element(:embed_type) do - has_text?(embed_type) - end + has_element? :snippet_description_field, text: snippet_description end def has_visibility_type?(visibility_type) @@ -52,6 +75,30 @@ module QA has_text?(file_content) end end + + def click_edit_button + finished_loading? + click_element(:snippet_action_button, action: 'Edit') + end + + def click_delete_button + finished_loading? + click_element(:snippet_action_button, action: 'Delete') + click_element(:delete_snippet_button) + finished_loading? # wait for the page to reload after deletion + end + + def get_repository_uri_http + finished_loading? + click_element(:clone_button) + Git::Location.new(find_element(:copy_http_url_button)['data-clipboard-text']).uri.to_s + end + + def get_repository_uri_ssh + finished_loading? + click_element(:clone_button) + Git::Location.new(find_element(:copy_ssh_url_button)['data-clipboard-text']).uri.to_s + end end end end diff --git a/qa/qa/page/file/shared/commit_button.rb b/qa/qa/page/file/shared/commit_button.rb index 9ea4f4e7818..c1c5907f27d 100644 --- a/qa/qa/page/file/shared/commit_button.rb +++ b/qa/qa/page/file/shared/commit_button.rb @@ -5,7 +5,11 @@ module QA module File module Shared module CommitButton + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/projects/_commit_button.html.haml' do element :commit_button end diff --git a/qa/qa/page/file/shared/commit_message.rb b/qa/qa/page/file/shared/commit_message.rb index ce3b1e9939c..823ce7bf7f9 100644 --- a/qa/qa/page/file/shared/commit_message.rb +++ b/qa/qa/page/file/shared/commit_message.rb @@ -5,7 +5,11 @@ module QA module File module Shared module CommitMessage + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/shared/_commit_message_container.html.haml' do element :commit_message, "text_area_tag 'commit_message'" # rubocop:disable QA/ElementWithPattern end diff --git a/qa/qa/page/file/shared/editor.rb b/qa/qa/page/file/shared/editor.rb index 448c09cfbca..ce4465d2a5c 100644 --- a/qa/qa/page/file/shared/editor.rb +++ b/qa/qa/page/file/shared/editor.rb @@ -5,7 +5,11 @@ module QA module File module Shared module Editor + extend QA::Page::PageConcern + def self.included(base) + super + base.view 'app/views/projects/blob/_editor.html.haml' do element :editor end diff --git a/qa/qa/page/group/sub_menus/common.rb b/qa/qa/page/group/sub_menus/common.rb index 96efc8da98d..86102f70d29 100644 --- a/qa/qa/page/group/sub_menus/common.rb +++ b/qa/qa/page/group/sub_menus/common.rb @@ -5,9 +5,12 @@ module QA module Group module SubMenus module Common + extend QA::Page::PageConcern include QA::Page::SubMenus::Common def self.included(base) + super + base.class_eval do view 'app/views/layouts/nav/sidebar/_group.html.haml' do element :group_sidebar diff --git a/qa/qa/page/main/terms.rb b/qa/qa/page/main/terms.rb index a4928f24397..a0de267fb31 100644 --- a/qa/qa/page/main/terms.rb +++ b/qa/qa/page/main/terms.rb @@ -1,20 +1,22 @@ # frozen_string_literal: true module QA - module Page::Main - class Terms < Page::Base - view 'app/views/layouts/terms.html.haml' do - element :user_avatar, required: true - end + module Page + module Main + class Terms < Page::Base + view 'app/views/layouts/terms.html.haml' do + element :user_avatar, required: true + end - view 'app/views/users/terms/index.html.haml' do - element :terms_content, required: true + view 'app/views/users/terms/index.html.haml' do + element :terms_content, required: true - element :accept_terms_button - end + element :accept_terms_button + end - def accept_terms - click_element :accept_terms_button, Page::Main::Menu + def accept_terms + click_element :accept_terms_button, Page::Main::Menu + end end end end diff --git a/qa/qa/page/page_concern.rb b/qa/qa/page/page_concern.rb new file mode 100644 index 00000000000..6ba2d27f574 --- /dev/null +++ b/qa/qa/page/page_concern.rb @@ -0,0 +1,16 @@ +module QA + module Page + module PageConcern + def included(base) + unless base.is_a?(Class) + raise "Expected #{self} to be prepended to a class, but #{base} is a module!" + end + + unless base.ancestors.include?(::QA::Page::Base) + raise "Expected #{self} to be prepended to a class that inherits from ::QA::Page::Base, but #{base} doesn't!" + end + end + alias_method :prepended, :included + end + end +end diff --git a/qa/qa/page/profile/personal_access_tokens.rb b/qa/qa/page/profile/personal_access_tokens.rb index 7069e7d3e4f..fd191fa3e27 100644 --- a/qa/qa/page/profile/personal_access_tokens.rb +++ b/qa/qa/page/profile/personal_access_tokens.rb @@ -6,9 +6,9 @@ module QA module Page module Profile class PersonalAccessTokens < Page::Base - view 'app/views/shared/_personal_access_tokens_form.html.haml' do + view 'app/views/shared/access_tokens/_form.html.haml' do element :expiry_date_field - element :personal_access_token_name_field + element :access_token_name_field element :create_token_button end @@ -16,15 +16,15 @@ module QA element :api_radio, 'qa-#{scope}-radio' # rubocop:disable QA/ElementWithPattern, Lint/InterpolationCheck end - view 'app/views/shared/_personal_access_tokens_created_container.html.haml' do - element :created_personal_access_token + view 'app/views/shared/access_tokens/_created_container.html.haml' do + element :created_access_token end - view 'app/views/shared/_personal_access_tokens_table.html.haml' do + view 'app/views/shared/access_tokens/_table.html.haml' do element :revoke_button end def fill_token_name(name) - fill_element(:personal_access_token_name_field, name) + fill_element(:access_token_name_field, name) end def check_api @@ -36,7 +36,7 @@ module QA end def created_access_token - find_element(:created_personal_access_token, wait: 30).value + find_element(:created_access_token, wait: 30).value end def fill_expiry_date(date) diff --git a/qa/qa/page/profile/ssh_keys.rb b/qa/qa/page/profile/ssh_keys.rb index 082202f91ca..810877e21ad 100644 --- a/qa/qa/page/profile/ssh_keys.rb +++ b/qa/qa/page/profile/ssh_keys.rb @@ -5,6 +5,7 @@ module QA module Profile class SSHKeys < Page::Base view 'app/views/profiles/keys/_form.html.haml' do + element :key_expiry_date_field element :key_title_field element :key_public_key_field element :add_key_button @@ -19,17 +20,26 @@ module QA end def add_key(public_key, title) - fill_element :key_public_key_field, public_key - fill_element :key_title_field, title + fill_element(:key_public_key_field, public_key) + fill_element(:key_title_field, title) + # Expire in 2 days just in case the key is created just before midnight + fill_expiry_date(Date.today + 2) - click_element :add_key_button + click_element(:add_key_button) + end + + def fill_expiry_date(date) + date = date.strftime('%m/%d/%Y') if date.is_a?(Date) + Date.strptime(date, '%m/%d/%Y') rescue ArgumentError raise "Expiry date must be in mm/dd/yyyy format" + + fill_element(:key_expiry_date_field, date) end def remove_key(title) click_link(title) accept_alert do - click_element :delete_key_button + click_element(:delete_key_button) end end diff --git a/qa/qa/page/project/issue/index.rb b/qa/qa/page/project/issue/index.rb index b5ad63ab8de..ace2537fc0e 100644 --- a/qa/qa/page/project/issue/index.rb +++ b/qa/qa/page/project/issue/index.rb @@ -9,6 +9,15 @@ module QA element :assignee_link end + view 'app/views/projects/issues/export_csv/_button.html.haml' do + element :export_as_csv_button + end + + view 'app/views/projects/issues/export_csv/_modal.html.haml' do + element :export_issues_button + element :export_issues_modal + end + view 'app/views/projects/issues/_issue.html.haml' do element :issue element :issue_link, 'link_to issue.title' # rubocop:disable QA/ElementWithPattern @@ -34,6 +43,18 @@ module QA click_element :closed_issues_link end + def click_export_as_csv_button + click_element(:export_as_csv_button) + end + + def click_export_issues_button + click_element(:export_issues_button) + end + + def export_issues_modal + find_element(:export_issues_modal) + end + def has_assignee_link_count?(count) all_elements(:assignee_link, count: count) end diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb index 8365ecb6348..dd74ff28763 100644 --- a/qa/qa/page/project/issue/show.rb +++ b/qa/qa/page/project/issue/show.rb @@ -7,6 +7,7 @@ module QA class Show < Page::Base include Page::Component::Issuable::Common include Page::Component::Note + include Page::Component::DesignManagement view 'app/assets/javascripts/notes/components/comment_form.vue' do element :comment_button @@ -56,6 +57,23 @@ module QA element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern end + view 'app/views/projects/issues/_tabs.html.haml' do + element :discussion_tab_link + element :discussion_tab_content + element :designs_tab_link + element :designs_tab_content + end + + def click_discussion_tab + click_element(:discussion_tab_link) + active_element?(:discussion_tab_content) + end + + def click_designs_tab + click_element(:designs_tab_link) + active_element?(:designs_tab_content) + end + def click_milestone_link click_element(:milestone_link) end diff --git a/qa/qa/page/project/job/show.rb b/qa/qa/page/project/job/show.rb index 26db2f20c1b..971b8c5e5f8 100644 --- a/qa/qa/page/project/job/show.rb +++ b/qa/qa/page/project/job/show.rb @@ -1,51 +1,55 @@ # frozen_string_literal: true -module QA::Page - module Project::Job - class Show < QA::Page::Base - include Component::CiBadgeLink +module QA + module Page + module Project + module Job + class Show < QA::Page::Base + include Component::CiBadgeLink - view 'app/assets/javascripts/jobs/components/log/log.vue' do - element :job_log_content - end + view 'app/assets/javascripts/jobs/components/log/log.vue' do + element :job_log_content + end - view 'app/assets/javascripts/jobs/components/stages_dropdown.vue' do - element :pipeline_path - end + view 'app/assets/javascripts/jobs/components/stages_dropdown.vue' do + element :pipeline_path + end - view 'app/assets/javascripts/jobs/components/sidebar.vue' do - element :retry_button - end + view 'app/assets/javascripts/jobs/components/sidebar.vue' do + element :retry_button + end - def successful?(timeout: 60) - 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) + def successful?(timeout: 60) + 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) - passed? - end + passed? + end - # Reminder: You may wish to wait for a particular job status before checking output - def output(wait: 5) - result = '' + # Reminder: You may wish to wait for a particular job status before checking output + def output(wait: 5) + result = '' - wait_until(reload: false, max_duration: wait, sleep_interval: 1) do - result = find_element(:job_log_content).text + wait_until(reload: false, max_duration: wait, sleep_interval: 1) do + result = find_element(:job_log_content).text - result.include?('Job') - end + result.include?('Job') + end - result - end + result + end - def retry! - click_element :retry_button - end + def retry! + click_element :retry_button + end - private + private - def loaded?(wait: 60) - wait_until(reload: true, max_duration: wait, sleep_interval: 1) do - has_element?(:job_log_content, wait: 1) + def loaded?(wait: 60) + wait_until(reload: true, max_duration: wait, sleep_interval: 1) do + has_element?(:job_log_content, wait: 1) + end + end end end end diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb index 97214e22820..f6c015f64ea 100644 --- a/qa/qa/page/project/new.rb +++ b/qa/qa/page/project/new.rb @@ -5,6 +5,7 @@ module QA module Project class New < Page::Base include Page::Component::Select2 + include Page::Component::Project::Templates view 'app/views/projects/new.html.haml' do element :project_create_from_template_tab @@ -26,6 +27,11 @@ module QA element :import_github, "icon('github', text: 'GitHub')" # rubocop:disable QA/ElementWithPattern end + view 'app/views/projects/project_templates/_built_in_templates.html.haml' do + element :use_template_button + element :template_option_row + end + def choose_test_namespace choose_namespace(Runtime::Namespace.path) end diff --git a/qa/qa/page/project/operations/kubernetes/index.rb b/qa/qa/page/project/operations/kubernetes/index.rb index 84b58e9ea5b..0c92f9a9f28 100644 --- a/qa/qa/page/project/operations/kubernetes/index.rb +++ b/qa/qa/page/project/operations/kubernetes/index.rb @@ -17,6 +17,10 @@ module QA def has_cluster?(cluster) has_element?(:cluster, cluster_name: cluster.to_s) end + + def click_on_cluster(cluster) + click_on cluster.cluster_name + end end end end diff --git a/qa/qa/page/project/operations/metrics/show.rb b/qa/qa/page/project/operations/metrics/show.rb index 020a3a1d5f8..2228cca1d3d 100644 --- a/qa/qa/page/project/operations/metrics/show.rb +++ b/qa/qa/page/project/operations/metrics/show.rb @@ -14,17 +14,22 @@ module QA element :dashboards_filter_dropdown element :environments_dropdown element :edit_dashboard_button - element :show_last_dropdown + element :range_picker_dropdown end view 'app/assets/javascripts/monitoring/components/duplicate_dashboard_form.vue' do element :duplicate_dashboard_filename_field end - view 'app/assets/javascripts/monitoring/components/panel_type.vue' do + view 'app/assets/javascripts/monitoring/components/dashboard_panel.vue' do element :prometheus_graph_widgets element :prometheus_widgets_dropdown element :alert_widget_menu_item + element :generate_chart_link_menu_item + end + + view 'app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue' do + element :quick_range_item end def wait_for_metrics @@ -66,9 +71,18 @@ module QA end def show_last(range = '8 hours') - click_element :show_last_dropdown - within_element :show_last_dropdown do - click_on range + all_elements(:range_picker_dropdown, minimum: 1).first.click + click_element :quick_range_item, text: range + end + + def copy_link_to_first_chart + all_elements(:prometheus_widgets_dropdown, minimum: 1).first.click + find_element(:generate_chart_link_menu_item)['data-clipboard-text'] + end + + def has_custom_metric?(metric) + within_element :prometheus_graphs do + has_text?(metric) end end diff --git a/qa/qa/page/project/pipeline/index.rb b/qa/qa/page/project/pipeline/index.rb index 327eedeaf91..54e4d0fb2fc 100644 --- a/qa/qa/page/project/pipeline/index.rb +++ b/qa/qa/page/project/pipeline/index.rb @@ -1,41 +1,45 @@ # frozen_string_literal: true -module QA::Page - module Project::Pipeline - class Index < QA::Page::Base - view 'app/assets/javascripts/pipelines/components/pipeline_url.vue' do - element :pipeline_url_link - end - - view 'app/assets/javascripts/pipelines/components/pipelines_table_row.vue' do - element :pipeline_commit_status - element :pipeline_retry_button - end - - def click_on_latest_pipeline - all_elements(:pipeline_url_link, minimum: 1, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).first.click - end - - def wait_for_latest_pipeline_success - wait_for_latest_pipeline_status { has_text?('passed') } - end - - def wait_for_latest_pipeline_completion - wait_for_latest_pipeline_status { has_text?('passed') || has_text?('failed') } - end - - def wait_for_latest_pipeline_status - wait_until(reload: false, max_duration: 360) do - within_element_by_index(:pipeline_commit_status, 0) { yield } - end - end - - def wait_for_latest_pipeline_success_or_retry - wait_for_latest_pipeline_completion - - if has_text?('failed') - click_element :pipeline_retry_button - wait_for_latest_pipeline_success +module QA + module Page + module Project + module Pipeline + class Index < QA::Page::Base + view 'app/assets/javascripts/pipelines/components/pipeline_url.vue' do + element :pipeline_url_link + end + + view 'app/assets/javascripts/pipelines/components/pipelines_table_row.vue' do + element :pipeline_commit_status + element :pipeline_retry_button + end + + def click_on_latest_pipeline + all_elements(:pipeline_url_link, minimum: 1, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).first.click + end + + def wait_for_latest_pipeline_success + wait_for_latest_pipeline_status { has_text?('passed') } + end + + def wait_for_latest_pipeline_completion + wait_for_latest_pipeline_status { has_text?('passed') || has_text?('failed') } + end + + def wait_for_latest_pipeline_status + wait_until(reload: false, max_duration: 360) do + within_element_by_index(:pipeline_commit_status, 0) { yield } + end + end + + def wait_for_latest_pipeline_success_or_retry + wait_for_latest_pipeline_completion + + if has_text?('failed') + click_element :pipeline_retry_button + wait_for_latest_pipeline_success + end + end end end end diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb index 1003b828a32..d22dfefc096 100644 --- a/qa/qa/page/project/pipeline/show.rb +++ b/qa/qa/page/project/pipeline/show.rb @@ -1,73 +1,77 @@ # frozen_string_literal: true -module QA::Page - module Project::Pipeline - class Show < QA::Page::Base - include Component::CiBadgeLink - - view 'app/assets/javascripts/vue_shared/components/header_ci_component.vue' do - element :pipeline_header, /header class.*ci-header-container.*/ # rubocop:disable QA/ElementWithPattern - end +module QA + module Page + module Project + module Pipeline + class Show < QA::Page::Base + include Component::CiBadgeLink + + view 'app/assets/javascripts/vue_shared/components/header_ci_component.vue' do + element :pipeline_header, /header class.*ci-header-container.*/ # rubocop:disable QA/ElementWithPattern + end - view 'app/assets/javascripts/pipelines/components/graph/graph_component.vue' do - element :pipeline_graph, /class.*pipeline-graph.*/ # rubocop:disable QA/ElementWithPattern - end + view 'app/assets/javascripts/pipelines/components/graph/graph_component.vue' do + element :pipeline_graph, /class.*pipeline-graph.*/ # rubocop:disable QA/ElementWithPattern + end - view 'app/assets/javascripts/pipelines/components/graph/job_item.vue' do - element :job_component, /class.*ci-job-component.*/ # rubocop:disable QA/ElementWithPattern - element :job_link - end + view 'app/assets/javascripts/pipelines/components/graph/job_item.vue' do + element :job_component, /class.*ci-job-component.*/ # rubocop:disable QA/ElementWithPattern + element :job_link + end - view 'app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue' do - element :linked_pipeline_button - end + view 'app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue' do + element :linked_pipeline_button + end - view 'app/assets/javascripts/vue_shared/components/ci_icon.vue' do - element :status_icon, 'ci-status-icon-${status}' # rubocop:disable QA/ElementWithPattern - end + view 'app/assets/javascripts/vue_shared/components/ci_icon.vue' do + element :status_icon, 'ci-status-icon-${status}' # rubocop:disable QA/ElementWithPattern + end - view 'app/views/projects/pipelines/_info.html.haml' do - element :pipeline_badges - end + view 'app/views/projects/pipelines/_info.html.haml' do + element :pipeline_badges + end - def running?(wait: 0) - within('.ci-header-container') do - page.has_content?('running', wait: wait) - end - end + def running?(wait: 0) + within('.ci-header-container') do + page.has_content?('running', wait: wait) + end + end - 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}", { wait: wait }.compact) + 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}", { wait: wait }.compact) + end + end end - end - end - def has_job?(job_name) - has_element?(:job_link, text: job_name) - end + def has_job?(job_name) + has_element?(:job_link, text: job_name) + end - def has_no_job?(job_name) - has_no_element?(:job_link, text: job_name) - end + def has_no_job?(job_name) + has_no_element?(:job_link, text: job_name) + end - def has_tag?(tag_name) - within_element(:pipeline_badges) do - has_selector?('.badge', text: tag_name) - end - end + def has_tag?(tag_name) + within_element(:pipeline_badges) do + has_selector?('.badge', text: tag_name) + end + end - def click_job(job_name) - click_element(:job_link, text: job_name) - end + def click_job(job_name) + click_element(:job_link, text: job_name) + end - def click_linked_job(project_name) - click_element(:linked_pipeline_button, text: /#{project_name}/) - end + def click_linked_job(project_name) + click_element(:linked_pipeline_button, text: /#{project_name}/) + end - def click_on_first_job - first('.js-pipeline-graph-job-link', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).click + def click_on_first_job + first('.js-pipeline-graph-job-link', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).click + end + end end end end diff --git a/qa/qa/page/project/settings/advanced.rb b/qa/qa/page/project/settings/advanced.rb index c95c47fa560..3bb5181a31c 100644 --- a/qa/qa/page/project/settings/advanced.rb +++ b/qa/qa/page/project/settings/advanced.rb @@ -57,6 +57,10 @@ module QA click_element :download_export_link end + def has_download_export_link? + has_element? :download_export_link + end + def archive_project page.accept_alert("Are you sure that you want to archive this project?") do click_element :archive_project_link diff --git a/qa/qa/page/project/settings/ci_cd.rb b/qa/qa/page/project/settings/ci_cd.rb index 46f93fad61e..aa27c030b78 100644 --- a/qa/qa/page/project/settings/ci_cd.rb +++ b/qa/qa/page/project/settings/ci_cd.rb @@ -5,12 +5,19 @@ module QA module Project module Settings class CICD < Page::Base - include Common + include QA::Page::Settings::Common view 'app/views/projects/settings/ci_cd/show.html.haml' do element :autodevops_settings_content element :runners_settings_content element :variables_settings_content + element :general_pipelines_settings_content + end + + def expand_general_pipelines(&block) + expand_section(:general_pipelines_settings_content) do + Settings::GeneralPipelines.perform(&block) + end end def expand_runners_settings(&block) diff --git a/qa/qa/page/project/settings/ci_variables.rb b/qa/qa/page/project/settings/ci_variables.rb index 6cdf40cd1da..de268b14aa2 100644 --- a/qa/qa/page/project/settings/ci_variables.rb +++ b/qa/qa/page/project/settings/ci_variables.rb @@ -5,7 +5,7 @@ module QA module Project module Settings class CiVariables < Page::Base - include Common + include QA::Page::Settings::Common view 'app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue' do element :ci_variable_key_field diff --git a/qa/qa/page/project/settings/common.rb b/qa/qa/page/project/settings/common.rb deleted file mode 100644 index f5f22623060..00000000000 --- a/qa/qa/page/project/settings/common.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module QA - module Page - module Project - module Settings - module Common - include QA::Page::Settings::Common - 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 c330d090ce6..8d655b0684e 100644 --- a/qa/qa/page/project/settings/deploy_keys.rb +++ b/qa/qa/page/project/settings/deploy_keys.rb @@ -5,7 +5,7 @@ module QA module Project module Settings class DeployKeys < Page::Base - view 'app/views/projects/deploy_keys/_form.html.haml' do + view 'app/views/shared/deploy_keys/_form.html.haml' do element :deploy_key_title, 'text_field :title' # rubocop:disable QA/ElementWithPattern element :deploy_key_key, 'text_area :key' # rubocop:disable QA/ElementWithPattern end diff --git a/qa/qa/page/project/settings/general_pipelines.rb b/qa/qa/page/project/settings/general_pipelines.rb new file mode 100644 index 00000000000..5a98849a41d --- /dev/null +++ b/qa/qa/page/project/settings/general_pipelines.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module QA + module Page + module Project + module Settings + class GeneralPipelines < Page::Base + include QA::Page::Settings::Common + + view 'app/views/projects/settings/ci_cd/_form.html.haml' do + element :build_coverage_regex_field + element :save_general_pipelines_changes_button + end + + def configure_coverage_regex(pattern) + fill_element :build_coverage_regex_field, pattern + click_element :save_general_pipelines_changes_button + end + end + end + end + end +end diff --git a/qa/qa/page/project/settings/incidents.rb b/qa/qa/page/project/settings/incidents.rb new file mode 100644 index 00000000000..94d5fc369ad --- /dev/null +++ b/qa/qa/page/project/settings/incidents.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module QA + module Page + module Project + module Settings + class Incidents < Page::Base + view 'app/views/projects/settings/operations/_incidents.html.haml' do + element :create_issue_checkbox + element :incident_templates_dropdown + element :save_changes_button + end + + def enable_issues_for_incidents + check_element :create_issue_checkbox + end + + def select_issue_template(template) + within_element :incident_templates_dropdown do + find(:option, template).select_option + end + end + + def save_incident_settings + click_element :save_changes_button + end + + def has_template?(template) + within_element :incident_templates_dropdown do + has_text?(template) + end + end + end + end + end + end +end diff --git a/qa/qa/page/project/settings/integrations.rb b/qa/qa/page/project/settings/integrations.rb new file mode 100644 index 00000000000..436a42fb093 --- /dev/null +++ b/qa/qa/page/project/settings/integrations.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module QA + module Page + module Project + module Settings + class Integrations < QA::Page::Base + view 'app/views/shared/integrations/_index.html.haml' do + element :prometheus_link, '{ data: { qa_selector: "#{integration.to_param' # rubocop:disable QA/ElementWithPattern + end + + def click_on_prometheus_integration + click_element :prometheus_link + end + end + end + end + end +end diff --git a/qa/qa/page/project/settings/main.rb b/qa/qa/page/project/settings/main.rb index 18d55598d90..efae497b6ba 100644 --- a/qa/qa/page/project/settings/main.rb +++ b/qa/qa/page/project/settings/main.rb @@ -5,7 +5,7 @@ module QA module Project module Settings class Main < Page::Base - include Common + include QA::Page::Settings::Common include Component::Select2 include SubMenus::Project diff --git a/qa/qa/page/project/settings/merge_request.rb b/qa/qa/page/project/settings/merge_request.rb index 7da2c9d168c..0092426b31f 100644 --- a/qa/qa/page/project/settings/merge_request.rb +++ b/qa/qa/page/project/settings/merge_request.rb @@ -5,7 +5,7 @@ module QA module Project module Settings class MergeRequest < QA::Page::Base - include Common + include QA::Page::Settings::Common view 'app/views/projects/edit.html.haml' do element :save_merge_request_changes diff --git a/qa/qa/page/project/settings/operations.rb b/qa/qa/page/project/settings/operations.rb new file mode 100644 index 00000000000..f6e005d3189 --- /dev/null +++ b/qa/qa/page/project/settings/operations.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module QA + module Page + module Project + module Settings + class Operations < Page::Base + include QA::Page::Settings::Common + + view 'app/views/projects/settings/operations/_incidents.html.haml' do + element :incidents_settings_content + end + + def expand_incidents(&block) + expand_section(:incidents_settings_content) do + Settings::Incidents.perform(&block) + end + end + end + end + end + end +end diff --git a/qa/qa/page/project/settings/repository.rb b/qa/qa/page/project/settings/repository.rb index 8810b971fda..8e9a24a4741 100644 --- a/qa/qa/page/project/settings/repository.rb +++ b/qa/qa/page/project/settings/repository.rb @@ -5,7 +5,7 @@ module QA module Project module Settings class Repository < Page::Base - include Common + include QA::Page::Settings::Common view 'app/views/projects/protected_branches/shared/_index.html.haml' do element :protected_branches_settings @@ -19,7 +19,7 @@ module QA element :deploy_tokens_settings end - view 'app/views/projects/deploy_keys/_index.html.haml' do + view 'app/views/shared/deploy_keys/_index.html.haml' do element :deploy_keys_settings end diff --git a/qa/qa/page/project/settings/services/prometheus.rb b/qa/qa/page/project/settings/services/prometheus.rb new file mode 100644 index 00000000000..8ae4ded535e --- /dev/null +++ b/qa/qa/page/project/settings/services/prometheus.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module QA + module Page + module Project + module Settings + module Services + class Prometheus < Page::Base + include Page::Component::CustomMetric + + view 'app/views/projects/services/prometheus/_custom_metrics.html.haml' do + element :custom_metrics_container + element :new_metric_button + end + + def click_on_custom_metric(custom_metric) + within_element :custom_metrics_container do + click_on custom_metric + end + end + + def click_on_new_metric + click_element :new_metric_button + end + + def has_custom_metric?(custom_metric) + within_element :custom_metrics_container do + has_text? custom_metric + end + end + end + end + end + end + end +end diff --git a/qa/qa/page/project/sub_menus/ci_cd.rb b/qa/qa/page/project/sub_menus/ci_cd.rb index 2f0bc8b9ba6..9405ea97fff 100644 --- a/qa/qa/page/project/sub_menus/ci_cd.rb +++ b/qa/qa/page/project/sub_menus/ci_cd.rb @@ -5,10 +5,14 @@ module QA module Project module SubMenus module CiCd - include Page::Project::SubMenus::Common + extend QA::Page::PageConcern def self.included(base) + super + base.class_eval do + include QA::Page::Project::SubMenus::Common + view 'app/views/layouts/nav/sidebar/_project.html.haml' do element :link_pipelines end diff --git a/qa/qa/page/project/sub_menus/common.rb b/qa/qa/page/project/sub_menus/common.rb index da759398cff..85bf932be4a 100644 --- a/qa/qa/page/project/sub_menus/common.rb +++ b/qa/qa/page/project/sub_menus/common.rb @@ -5,6 +5,7 @@ module QA module Project module SubMenus module Common + extend QA::Page::PageConcern include QA::Page::SubMenus::Common private diff --git a/qa/qa/page/project/sub_menus/issues.rb b/qa/qa/page/project/sub_menus/issues.rb index d27a250a300..c15a8ec4cc7 100644 --- a/qa/qa/page/project/sub_menus/issues.rb +++ b/qa/qa/page/project/sub_menus/issues.rb @@ -5,10 +5,14 @@ module QA module Project module SubMenus module Issues - include Page::Project::SubMenus::Common + extend QA::Page::PageConcern def self.included(base) + super + base.class_eval do + include QA::Page::Project::SubMenus::Common + view 'app/views/layouts/nav/sidebar/_project.html.haml' do element :issue_boards_link element :issues_item diff --git a/qa/qa/page/project/sub_menus/operations.rb b/qa/qa/page/project/sub_menus/operations.rb index bcbc1dc16d3..ff9c8a21174 100644 --- a/qa/qa/page/project/sub_menus/operations.rb +++ b/qa/qa/page/project/sub_menus/operations.rb @@ -5,12 +5,16 @@ module QA module Project module SubMenus module Operations - include Page::Project::SubMenus::Common + extend QA::Page::PageConcern def self.included(base) + super + base.class_eval do + include QA::Page::Project::SubMenus::Common + view 'app/views/layouts/nav/sidebar/_project.html.haml' do - element :link_operations + element :operations_link element :operations_environments_link element :operations_metrics_link end @@ -45,8 +49,8 @@ module QA def hover_operations within_sidebar do - scroll_to_element(:link_operations) - find_element(:link_operations).hover + scroll_to_element(:operations_link) + find_element(:operations_link).hover yield end diff --git a/qa/qa/page/project/sub_menus/project.rb b/qa/qa/page/project/sub_menus/project.rb index 6f1bc131f84..4af640301b9 100644 --- a/qa/qa/page/project/sub_menus/project.rb +++ b/qa/qa/page/project/sub_menus/project.rb @@ -5,10 +5,14 @@ module QA module Project module SubMenus module Project - include Common + extend QA::Page::PageConcern def self.included(base) + super + base.class_eval do + include QA::Page::Project::SubMenus::Common + view 'app/views/layouts/nav/sidebar/_project.html.haml' do element :project_link end diff --git a/qa/qa/page/project/sub_menus/repository.rb b/qa/qa/page/project/sub_menus/repository.rb index 65149e631f3..38d6b8e50f4 100644 --- a/qa/qa/page/project/sub_menus/repository.rb +++ b/qa/qa/page/project/sub_menus/repository.rb @@ -5,10 +5,14 @@ module QA module Project module SubMenus module Repository - include Page::Project::SubMenus::Common + extend QA::Page::PageConcern def self.included(base) + super + base.class_eval do + include QA::Page::Project::SubMenus::Common + view 'app/views/layouts/nav/sidebar/_project.html.haml' do element :project_menu_repo element :branches_link @@ -44,5 +48,3 @@ module QA end end end - -QA::Page::Project::SubMenus::Repository.prepend_if_ee('QA::EE::Page::Project::SubMenus::Repository') diff --git a/qa/qa/page/project/sub_menus/settings.rb b/qa/qa/page/project/sub_menus/settings.rb index 8be442ba35d..0dd4bd1817a 100644 --- a/qa/qa/page/project/sub_menus/settings.rb +++ b/qa/qa/page/project/sub_menus/settings.rb @@ -5,15 +5,20 @@ module QA module Project module SubMenus module Settings - include Page::Project::SubMenus::Common + extend QA::Page::PageConcern def self.included(base) + super + base.class_eval do + include QA::Page::Project::SubMenus::Common + view 'app/views/layouts/nav/sidebar/_project.html.haml' do element :settings_item element :link_members_settings element :general_settings_link element :integrations_settings_link + element :operations_settings_link end end end @@ -64,6 +69,14 @@ module QA end end + def go_to_operations_settings + hover_settings do + within_submenu do + click_element :operations_settings_link + end + end + end + private def hover_settings diff --git a/qa/qa/page/search/results.rb b/qa/qa/page/search/results.rb index 85f1d224935..55477db8804 100644 --- a/qa/qa/page/search/results.rb +++ b/qa/qa/page/search/results.rb @@ -1,53 +1,55 @@ # frozen_string_literal: true -module QA::Page - module Search - class Results < QA::Page::Base - view 'app/views/search/_category.html.haml' do - element :code_tab - element :projects_tab - end +module QA + module Page + module Search + class Results < QA::Page::Base + view 'app/views/search/_category.html.haml' do + element :code_tab + element :projects_tab + end - view 'app/views/search/results/_blob_data.html.haml' do - element :result_item_content - element :file_title_content - element :file_text_content - end + view 'app/views/search/results/_blob_data.html.haml' do + element :result_item_content + element :file_title_content + element :file_text_content + end - view 'app/views/shared/projects/_project.html.haml' do - element :project - end + view 'app/views/shared/projects/_project.html.haml' do + element :project + end - def switch_to_code - switch_to_tab(:code_tab) - end + def switch_to_code + switch_to_tab(:code_tab) + end - def switch_to_projects - switch_to_tab(:projects_tab) - end + def switch_to_projects + switch_to_tab(:projects_tab) + end - def has_file_in_project?(file_name, project_name) - has_element?(:result_item_content, text: "#{project_name}: #{file_name}") - end + def has_file_in_project?(file_name, project_name) + has_element?(:result_item_content, text: "#{project_name}: #{file_name}") + end - def has_file_with_content?(file_name, file_text) - within_element_by_index(:result_item_content, 0) do - break false unless has_element?(:file_title_content, text: file_name) + def has_file_with_content?(file_name, file_text) + within_element_by_index(:result_item_content, 0) do + break false unless has_element?(:file_title_content, text: file_name) - has_element?(:file_text_content, text: file_text) + has_element?(:file_text_content, text: file_text) + end end - end - def has_project?(project_name) - has_element?(:project, project_name: project_name) - end + def has_project?(project_name) + has_element?(:project, project_name: project_name) + end - private + private - def switch_to_tab(tab) - retry_until do - click_element(tab) - has_active_element?(tab) + def switch_to_tab(tab) + retry_until do + click_element(tab) + has_active_element?(tab) + end end end end |