Commit f11fbd88 authored by Sofia's avatar Sofia Committed by Walmyr Lima e Silva Filho

Refactor Page Objects and folder structure

This commit applies the page object pattern
for the metrics page under the operations submenu.

They are reflecting on EE too as adding a
custom metric is a paid feature.
parent 7dd5296d
...@@ -468,6 +468,7 @@ export default { ...@@ -468,6 +468,7 @@ export default {
ref="addMetricBtn" ref="addMetricBtn"
v-gl-modal="$options.addMetric.modalId" v-gl-modal="$options.addMetric.modalId"
variant="outline-success" variant="outline-success"
data-qa-selector="add_metric_button"
class="mr-2 mt-1" class="mr-2 mt-1"
>{{ $options.addMetric.title }}</gl-button >{{ $options.addMetric.title }}</gl-button
> >
......
...@@ -185,6 +185,7 @@ export default { ...@@ -185,6 +185,7 @@ export default {
name="prometheus_metric[title]" name="prometheus_metric[title]"
class="form-control" class="form-control"
:placeholder="s__('Metrics|e.g. Throughput')" :placeholder="s__('Metrics|e.g. Throughput')"
data-qa-selector="custom_metric_prometheus_title_field"
required required
/> />
<span class="form-text text-muted">{{ s__('Metrics|Used as a title for the chart') }}</span> <span class="form-text text-muted">{{ s__('Metrics|Used as a title for the chart') }}</span>
...@@ -208,6 +209,7 @@ export default { ...@@ -208,6 +209,7 @@ export default {
<gl-form-input <gl-form-input
id="prometheus_metric_query" id="prometheus_metric_query"
v-model.trim="query" v-model.trim="query"
data-qa-selector="custom_metric_prometheus_query_field"
name="prometheus_metric[query]" name="prometheus_metric[query]"
class="form-control" class="form-control"
:placeholder="s__('Metrics|e.g. rate(http_requests_total[5m])')" :placeholder="s__('Metrics|e.g. rate(http_requests_total[5m])')"
...@@ -245,6 +247,7 @@ export default { ...@@ -245,6 +247,7 @@ export default {
<gl-form-input <gl-form-input
id="prometheus_metric_y_label" id="prometheus_metric_y_label"
v-model="yLabel" v-model="yLabel"
data-qa-selector="custom_metric_prometheus_y_label_field"
name="prometheus_metric[y_label]" name="prometheus_metric[y_label]"
class="form-control" class="form-control"
:placeholder="s__('Metrics|e.g. Requests/second')" :placeholder="s__('Metrics|e.g. Requests/second')"
...@@ -264,6 +267,7 @@ export default { ...@@ -264,6 +267,7 @@ export default {
<gl-form-input <gl-form-input
id="prometheus_metric_unit" id="prometheus_metric_unit"
v-model="unit" v-model="unit"
data-qa-selector="custom_metric_prometheus_unit_label_field"
name="prometheus_metric[unit]" name="prometheus_metric[unit]"
class="form-control" class="form-control"
:placeholder="s__('Metrics|e.g. req/sec')" :placeholder="s__('Metrics|e.g. req/sec')"
...@@ -278,6 +282,7 @@ export default { ...@@ -278,6 +282,7 @@ export default {
<gl-form-input <gl-form-input
id="prometheus_metric_legend" id="prometheus_metric_legend"
v-model="legend" v-model="legend"
data-qa-selector="custom_metric_prometheus_legend_label_field"
name="prometheus_metric[legend]" name="prometheus_metric[legend]"
class="form-control" class="form-control"
:placeholder="s__('Metrics|e.g. HTTP requests')" :placeholder="s__('Metrics|e.g. HTTP requests')"
......
...@@ -296,7 +296,9 @@ module QA ...@@ -296,7 +296,9 @@ module QA
autoload :Show, 'qa/page/project/operations/kubernetes/show' autoload :Show, 'qa/page/project/operations/kubernetes/show'
end end
autoload :Metrics, 'qa/page/project/operations/metrics' module Metrics
autoload :Show, 'qa/page/project/operations/metrics/show'
end
end end
module Wiki module Wiki
......
...@@ -129,7 +129,9 @@ module QA ...@@ -129,7 +129,9 @@ module QA
autoload :Show, 'qa/ee/page/project/operations/kubernetes/show' autoload :Show, 'qa/ee/page/project/operations/kubernetes/show'
end end
autoload :Metrics, 'qa/ee/page/project/operations/metrics' module Metrics
autoload :Show, 'qa/ee/page/project/operations/metrics/show'
end
end end
module Packages module Packages
......
# frozen_string_literal: true
module QA
module EE
module Page
module Project
module Operations
module Metrics
EXPECTED_LABEL = 'Total (GB)'
def self.prepended(page)
page.module_eval do
view 'ee/app/assets/javascripts/monitoring/components/alert_widget_form.vue' do
element :alert_query_dropdown
element :alert_query_option
element :alert_threshold_field
end
end
end
def wait_for_alert(operator = '>', threshold = 0)
wait_until(reload: false) { has_alert?(operator, threshold) }
end
def has_alert?(operator = '>', threshold = 0)
within_element :prometheus_graphs do
has_text?([EXPECTED_LABEL, operator, threshold].join(' '))
end
end
def write_first_alert(operator = '>', threshold = 0)
open_first_alert_modal
click_on operator
fill_element :alert_threshold_field, threshold
within('.modal-content') { click_button(class: 'btn-success') }
end
def delete_first_alert
open_first_alert_modal
within('.modal-content') { click_button(class: 'btn-danger') }
wait_for_requests
end
def open_first_alert_modal
all_elements(:prometheus_widgets_dropdown, minimum: 1).first.click
click_element :alert_widget_menu_item
click_element :alert_query_dropdown unless has_element?(:alert_query_option, wait: 3)
all_elements(:alert_query_option, minimum: 1).first.click
end
end
end
end
end
end
end
# frozen_string_literal: true
module QA
module EE
module Page
module Project
module Operations
module Metrics
module Show
EXPECTED_LABEL = 'Total (GB)'
EXPECTED_TITLE_CUSTOM_METRIC = 'HTTP Requests (Total)'
def self.prepended(page)
page.module_eval do
view 'ee/app/assets/javascripts/monitoring/components/alert_widget_form.vue' do
element :alert_query_dropdown
element :alert_query_option
element :alert_threshold_field
end
view 'app/assets/javascripts/monitoring/components/dashboard.vue' do
element :add_metric_button
end
view 'ee/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
end
def wait_for_alert(operator = '>', threshold = 0)
wait_until(reload: false) { has_alert?(operator, threshold) }
end
def has_alert?(operator = '>', threshold = 0)
within_element :prometheus_graphs do
has_text?([EXPECTED_LABEL, operator, threshold].join(' '))
end
end
def write_first_alert(operator = '>', threshold = 0)
open_first_alert_modal
click_on operator
fill_element :alert_threshold_field, threshold
within('.modal-content') { click_button(class: 'btn-success') }
end
def delete_first_alert
open_first_alert_modal
within('.modal-content') { click_button(class: 'btn-danger') }
wait_for_requests
end
def open_first_alert_modal
all_elements(:prometheus_widgets_dropdown, minimum: 1).first.click
click_element :alert_widget_menu_item
click_element :alert_query_dropdown unless has_element?(:alert_query_option, wait: 3)
all_elements(:alert_query_option, minimum: 1).first.click
end
def add_custom_metric
open_add_metric_modal
fill_element :custom_metric_prometheus_title_field, EXPECTED_TITLE_CUSTOM_METRIC
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 has_custom_metric?
within_element :prometheus_graphs do
has_text?(EXPECTED_TITLE_CUSTOM_METRIC)
end
end
private
def open_add_metric_modal
click_element :add_metric_button
end
def save_changes
within('.modal-content') { click_button(class: 'btn-success') }
end
end
end
end
end
end
end
end
...@@ -7,7 +7,7 @@ image: alpine:latest ...@@ -7,7 +7,7 @@ image: alpine:latest
variables: variables:
# AUTO_DEVOPS_DOMAIN is the application deployment domain and should be set as a variable at the group or project level. # AUTO_DEVOPS_DOMAIN is the application deployment domain and should be set as a variable at the group or project level.
AUTO_DEVOPS_DOMAIN: my-fake-domain.com AUTO_DEVOPS_DOMAIN: $AUTO_DEVOPS_DOMAIN
POSTGRES_USER: user POSTGRES_USER: user
POSTGRES_PASSWORD: testing-password POSTGRES_PASSWORD: testing-password
......
# frozen_string_literal: true
module QA
module Page
module Project
module Operations
class Metrics < Page::Base
EXPECTED_TITLE = 'Memory Usage (Total)'
LOADING_MESSAGE = 'Waiting for performance data'
view 'app/assets/javascripts/monitoring/components/dashboard.vue' do
element :prometheus_graphs
end
view 'app/assets/javascripts/monitoring/components/panel_type.vue' do
element :prometheus_graph_widgets
element :prometheus_widgets_dropdown
element :alert_widget_menu_item
end
def wait_for_metrics
wait_for_data
return if has_metrics?
wait_until(max_duration: 180) do
wait_for_data
has_metrics?
end
end
def wait_for_data
wait_until(reload: false) { !has_text?(LOADING_MESSAGE) } if has_text?(LOADING_MESSAGE)
end
def has_metrics?
within_element :prometheus_graphs do
has_text?(EXPECTED_TITLE)
end
end
end
end
end
end
end
QA::Page::Project::Operations::Metrics.prepend_if_ee('QA::EE::Page::Project::Operations::Metrics')
# frozen_string_literal: true
module QA
module Page
module Project
module Operations
module Metrics
class Show < Page::Base
EXPECTED_TITLE = 'Memory Usage (Total)'
LOADING_MESSAGE = 'Waiting for performance data'
view 'app/assets/javascripts/monitoring/components/dashboard.vue' do
element :prometheus_graphs
end
view 'app/assets/javascripts/monitoring/components/panel_type.vue' do
element :prometheus_graph_widgets
element :prometheus_widgets_dropdown
element :alert_widget_menu_item
end
def wait_for_metrics
wait_for_data
return if has_metrics?
wait_until(max_duration: 180) do
wait_for_data
has_metrics?
end
end
def has_metrics?
within_element :prometheus_graphs do
has_text?(EXPECTED_TITLE)
end
end
private
def wait_for_data
wait_until(reload: false) { !has_text?(LOADING_MESSAGE) } if has_text?(LOADING_MESSAGE)
end
end
end
end
end
end
end
QA::Page::Project::Operations::Metrics::Show.prepend_if_ee('QA::EE::Page::Project::Operations::Metrics::Show')
# frozen_string_literal: true
module QA
context 'Monitor' do
describe 'Metrics with Prometheus', :orchestrated, :kubernetes, quarantine: { type: :new } do
before do
@cluster = Service::KubernetesCluster.new.create!
Flow::Login.sign_in
create_project_to_monitor
wait_for_deployment
end
after do
@cluster&.remove!
end
it 'configures custom metrics in Prometheus running on a Kubernetes cluster' do
Page::Project::Operations::Metrics::Show.perform do |metrics|
metrics.add_custom_metric
end
Page::Project::Menu.perform(&:go_to_operations_metrics)
Page::Project::Operations::Metrics::Show.perform do |metrics|
expect(metrics).to have_custom_metric
end
end
private
def wait_for_deployment
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
Page::Project::Pipeline::Index.perform(&:wait_for_latest_pipeline_success_or_retry)
Page::Project::Menu.perform(&:go_to_operations_metrics)
end
def create_project_to_monitor
@project = Resource::Project.fabricate_via_api! do |p|
p.name = 'cluster-with-prometheus'
p.description = 'Cluster with Prometheus'
end
@cluster_props = Resource::KubernetesCluster.fabricate_via_browser_ui! do |c|
c.project = @project
c.cluster = @cluster
c.install_helm_tiller = true
c.install_prometheus = true
c.install_ingress = true
end
Resource::CiVariable.fabricate_via_api! do |resource|
resource.project = @project
resource.key = 'AUTO_DEVOPS_DOMAIN'
resource.value = @cluster_props.ingress_ip
resource.masked = false
end
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = @project
push.directory = Pathname
.new(__dir__)
.join('../../../../../../fixtures/monitored_auto_devops')
push.commit_message = 'Create AutoDevOps compatible Project for Monitoring'
end
end
end
end
end
...@@ -18,7 +18,7 @@ module QA ...@@ -18,7 +18,7 @@ module QA
push_repository(project) push_repository(project)
wait_for_deployment wait_for_deployment
Page::Project::Operations::Metrics.perform do |metrics| Page::Project::Operations::Metrics::Show.perform do |metrics|
verify_metrics(metrics) verify_metrics(metrics)
verify_add_alert(metrics) verify_add_alert(metrics)
verify_edit_alert(metrics) verify_edit_alert(metrics)
...@@ -54,6 +54,13 @@ module QA ...@@ -54,6 +54,13 @@ module QA
.join('../../../../../../fixtures/monitored_auto_devops') .join('../../../../../../fixtures/monitored_auto_devops')
push.commit_message = 'Create Auto DevOps compatible gitlab-ci.yml' push.commit_message = 'Create Auto DevOps compatible gitlab-ci.yml'
end end
Resource::CiVariable.fabricate_via_api! do |resource|
resource.project = project
resource.key = 'AUTO_DEVOPS_DOMAIN'
resource.value = 'my-fake-domain.com'
resource.masked = false
end
end end
def wait_for_deployment def wait_for_deployment
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment