diff --git a/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_health_monitor.json b/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_health_monitor.json
new file mode 100644
index 000000000..52ea935ed
--- /dev/null
+++ b/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_health_monitor.json
@@ -0,0 +1,58 @@
+{
+ "name": "sample_cluster_metrics_health_monitor",
+ "type": "monitor",
+ "monitor_type": "cluster_metrics_monitor",
+ "enabled": true,
+ "schedule": {
+ "period": {
+ "unit": "MINUTES",
+ "interval": 1
+ }
+ },
+ "inputs": [
+ {
+ "uri": {
+ "api_type": "CLUSTER_HEALTH",
+ "path": "_cluster/health/",
+ "path_params": "",
+ "url": "http://localhost:9200/_cluster/health/"
+ }
+ }
+ ],
+ "triggers": [],
+ "ui_metadata": {
+ "schedule": {
+ "timezone": null,
+ "frequency": "interval",
+ "period": {
+ "unit": "MINUTES",
+ "interval": 1
+ },
+ "daily": 0,
+ "weekly": {
+ "tue": false,
+ "wed": false,
+ "thur": false,
+ "sat": false,
+ "fri": false,
+ "mon": false,
+ "sun": false
+ },
+ "monthly": {
+ "type": "day",
+ "day": 1
+ },
+ "cronExpression": "0 */1 * * *"
+ },
+ "search": {
+ "searchType": "clusterMetrics",
+ "timeField": "",
+ "aggregations": [],
+ "groupBy": [],
+ "bucketValue": 1,
+ "bucketUnitOfTime": "h",
+ "filters": []
+ },
+ "monitor_type": "cluster_metrics_monitor"
+ }
+}
diff --git a/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_stats_monitor.json b/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_stats_monitor.json
new file mode 100644
index 000000000..a258b0586
--- /dev/null
+++ b/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_stats_monitor.json
@@ -0,0 +1,73 @@
+{
+ "name": "sample_cluster_metrics_stats_monitor",
+ "type": "monitor",
+ "monitor_type": "cluster_metrics_monitor",
+ "enabled": true,
+ "schedule": {
+ "period": {
+ "unit": "MINUTES",
+ "interval": 1
+ }
+ },
+ "inputs": [
+ {
+ "uri": {
+ "api_type": "CLUSTER_STATS",
+ "path": "_cluster/stats/",
+ "path_params": "",
+ "url": "http://localhost:9200/_cluster/stats/"
+ }
+ }
+ ],
+ "triggers": [
+ {
+ "query_level_trigger": {
+ "id": "Y5mmA4kBIezNcMbMJnEy",
+ "name": "sample_cluster_metrics_stats_monitor-trigger1",
+ "severity": "1",
+ "condition": {
+ "script": {
+ "source": "ctx.results[0].indices.count >= 0",
+ "lang": "painless"
+ }
+ },
+ "actions": []
+ }
+ }
+ ],
+ "ui_metadata": {
+ "schedule": {
+ "timezone": null,
+ "frequency": "interval",
+ "period": {
+ "unit": "MINUTES",
+ "interval": 1
+ },
+ "daily": 0,
+ "weekly": {
+ "tue": false,
+ "wed": false,
+ "thur": false,
+ "sat": false,
+ "fri": false,
+ "mon": false,
+ "sun": false
+ },
+ "monthly": {
+ "type": "day",
+ "day": 1
+ },
+ "cronExpression": "0 */1 * * *"
+ },
+ "search": {
+ "searchType": "clusterMetrics",
+ "timeField": "",
+ "aggregations": [],
+ "groupBy": [],
+ "bucketValue": 1,
+ "bucketUnitOfTime": "h",
+ "filters": []
+ },
+ "monitor_type": "cluster_metrics_monitor"
+ }
+}
diff --git a/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_composite_level_monitor.json b/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_composite_level_monitor.json
new file mode 100644
index 000000000..9b1f67bf4
--- /dev/null
+++ b/cypress/fixtures/plugins/alerting-dashboards-plugin/sample_composite_level_monitor.json
@@ -0,0 +1,274 @@
+{
+ "sample_composite_monitor": {
+ "type": "workflow",
+ "schema_version": 0,
+ "name": "sampleComponentLevelMonitor",
+ "workflow_type": "composite",
+ "enabled": true,
+ "enabled_time": 1686908176848,
+ "schedule": {
+ "period": {
+ "interval": 1,
+ "unit": "MINUTES"
+ }
+ },
+ "inputs": [
+ {
+ "composite_input": {
+ "sequence": {
+ "delegates": [
+ {
+ "order": 1,
+ "monitor_id": "qdYBw4gB2qeAWe54jQyZ"
+ },
+ {
+ "order": 2,
+ "monitor_id": "rtYBw4gB2qeAWe54wAx5"
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "triggers": [
+ {
+ "chained_alert_trigger": {
+ "id": "pNaQw4gB2qeAWe54Fg2U",
+ "name": "sample_trigger",
+ "severity": "1",
+ "condition": {
+ "script": {
+ "source": "(monitor[id=qdYBw4gB2qeAWe54jQyZ]) && (monitor[id=rtYBw4gB2qeAWe54wAx5])",
+ "lang": "painless"
+ }
+ },
+ "actions": [
+ {
+ "id": "pdaQw4gB2qeAWe54Fg2U",
+ "name": "sample_channel",
+ "destination_id": "6dYFw4gB2qeAWe54NgyL",
+ "message_template": {
+ "source": "Monitor {{ctx.monitor.name}} just entered alert status. Please investigate the issue.\n - Trigger: {{ctx.trigger.name}}\n - Severity: {{ctx.trigger.severity}}\n - Period start: {{ctx.periodStart}}\n - Period end: {{ctx.periodEnd}}",
+ "lang": "mustache"
+ },
+ "throttle_enabled": false,
+ "subject_template": {
+ "source": "Monitor {{ctx.monitor.name}} triggered an alert {{ctx.trigger.name}}",
+ "lang": "mustache"
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "last_update_time": 1686908180116,
+ "owner": "alerting",
+ "monitor_type": "composite"
+ },
+ "sample_composite_index": {
+ "mappings": {
+ "properties": {
+ "audit_category": {
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword",
+ "ignore_above": 256
+ }
+ }
+ },
+ "audit_node_host_name": {
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword",
+ "ignore_above": 256
+ }
+ }
+ },
+ "audit_node_id": {
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword",
+ "ignore_above": 256
+ }
+ }
+ }
+ }
+ }
+ },
+ "sample_composite_associated_monitor_1": {
+ "name": "monitorOne",
+ "type": "monitor",
+ "monitor_type": "doc_level_monitor",
+ "enabled": false,
+ "schedule": {
+ "period": {
+ "unit": "MINUTES",
+ "interval": 1
+ }
+ },
+ "inputs": [
+ {
+ "doc_level_input": {
+ "description": "",
+ "indices": ["sample_index_1"],
+ "queries": [
+ {
+ "id": "monitor_1_query_1",
+ "name": "monitor_1_query_1",
+ "query": "NOT (audit_category:\"sample_text\")",
+ "tags": []
+ },
+ {
+ "id": "monitor_1_query_2",
+ "name": "monitor_1_query_2",
+ "query": "NOT (audit_node_host_name:\"sample_text\")",
+ "tags": []
+ },
+ {
+ "id": "monitor_1_query_3",
+ "name": "monitor_1_query_3",
+ "query": "NOT (audit_node_id:\"sample_text\")",
+ "tags": []
+ }
+ ]
+ }
+ }
+ ],
+ "triggers": [
+ {
+ "document_level_trigger": {
+ "id": "sample_trigger_id_1",
+ "name": "monitor_1_query_2",
+ "severity": "1",
+ "condition": {
+ "script": {
+ "source": "query[name=monitor_1_query_1] || query[name=monitor_1_query_2] && query[name=monitor_1_query_3]",
+ "lang": "painless"
+ }
+ },
+ "actions": []
+ }
+ }
+ ]
+ },
+ "sample_composite_associated_monitor_2": {
+ "name": "monitorTwo",
+ "type": "monitor",
+ "monitor_type": "doc_level_monitor",
+ "enabled": false,
+ "schedule": {
+ "period": {
+ "unit": "MINUTES",
+ "interval": 1
+ }
+ },
+ "inputs": [
+ {
+ "doc_level_input": {
+ "description": "",
+ "indices": ["sample_index_2"],
+ "queries": [
+ {
+ "id": "monitor_2_query_1",
+ "name": "monitor_2_query_1",
+ "query": "NOT (audit_category:\"sample_text\")",
+ "tags": []
+ },
+ {
+ "id": "monitor_2_query_2",
+ "name": "monitor_2_query_2",
+ "query": "NOT (audit_node_host_name:\"sample_text\")",
+ "tags": []
+ },
+ {
+ "id": "monitor_2_query_3",
+ "name": "monitor_2_query_3",
+ "query": "NOT (audit_node_id:\"sample_text\")",
+ "tags": []
+ }
+ ]
+ }
+ }
+ ],
+ "triggers": [
+ {
+ "document_level_trigger": {
+ "id": "sample_trigger_2",
+ "name": "monitor_2_query_2",
+ "severity": "1",
+ "condition": {
+ "script": {
+ "source": "query[name=monitor_2_query_1] || query[name=monitor_2_query_2] && query[name=monitor_2_query_3]",
+ "lang": "painless"
+ }
+ },
+ "actions": []
+ }
+ }
+ ]
+ },
+ "sample_composite_associated_monitor_3": {
+ "name": "monitorThree",
+ "type": "monitor",
+ "monitor_type": "doc_level_monitor",
+ "enabled": false,
+ "schedule": {
+ "period": {
+ "unit": "MINUTES",
+ "interval": 1
+ }
+ },
+ "inputs": [
+ {
+ "doc_level_input": {
+ "description": "",
+ "indices": ["sample_index_2"],
+ "queries": [
+ {
+ "id": "monitor_2_query_1",
+ "name": "monitor_2_query_1",
+ "query": "NOT (audit_category:\"sample_text\")",
+ "tags": []
+ },
+ {
+ "id": "monitor_2_query_2",
+ "name": "monitor_2_query_2",
+ "query": "NOT (audit_node_host_name:\"sample_text\")",
+ "tags": []
+ },
+ {
+ "id": "monitor_2_query_3",
+ "name": "monitor_2_query_3",
+ "query": "NOT (audit_node_id:\"sample_text\")",
+ "tags": []
+ }
+ ]
+ }
+ }
+ ],
+ "triggers": [
+ {
+ "document_level_trigger": {
+ "id": "sample_trigger_2",
+ "name": "monitor_2_query_2",
+ "severity": "1",
+ "condition": {
+ "script": {
+ "source": "query[name=monitor_2_query_1] || query[name=monitor_2_query_2] && query[name=monitor_2_query_3]",
+ "lang": "painless"
+ }
+ },
+ "actions": []
+ }
+ }
+ ]
+ },
+ "sample_composite_associated_index_document": {
+ "audit_category": "FAILED_LOGIN",
+ "audit_node_host_name": "127.0.0.1",
+ "audit_node_id": "sample_node_id"
+ }
+}
diff --git a/cypress/integration/plugins/alerting-dashboards-plugin/cluster_metrics_monitor_spec.js b/cypress/integration/plugins/alerting-dashboards-plugin/cluster_metrics_monitor_spec.js
index be3075ff4..9d6c165ec 100644
--- a/cypress/integration/plugins/alerting-dashboards-plugin/cluster_metrics_monitor_spec.js
+++ b/cypress/integration/plugins/alerting-dashboards-plugin/cluster_metrics_monitor_spec.js
@@ -105,10 +105,12 @@ describe('ClusterMetricsMonitor', () => {
cy.contains('There are no existing monitors');
// Go to create monitor page
- cy.contains('Create monitor').click();
+ cy.contains('Create monitor', { timeout: 20000 }).click({ force: true });
// Select ClusterMetrics radio card
- cy.get('[data-test-subj="clusterMetricsMonitorRadioCard"]').click();
+ cy.get('[data-test-subj="clusterMetricsMonitorRadioCard"]').click({
+ force: true,
+ });
// Wait for input to load and then type in the monitor name
cy.get('input[name="name"]').type(SAMPLE_CLUSTER_METRICS_HEALTH_MONITOR);
@@ -119,7 +121,7 @@ describe('ClusterMetricsMonitor', () => {
);
// Confirm the Query parameters field is present and described as "optional"
- cy.contains('Query parameters - optional');
+ cy.contains('Path parameters - optional');
cy.get('[data-test-subj="clusterMetricsParamsFieldText"]');
// Press the 'Run for response' button
@@ -144,7 +146,7 @@ describe('ClusterMetricsMonitor', () => {
// .type('{downarrow}{enter}');
// Click the create button
- cy.get('button').contains('Create').click();
+ cy.get('button').contains('Create').click({ force: true });
// Confirm we can see only one row in the trigger list by checking
element
cy.contains('This table contains 1 row');
@@ -153,7 +155,7 @@ describe('ClusterMetricsMonitor', () => {
cy.contains(SAMPLE_TRIGGER);
// Go back to the Monitors list
- cy.get('a').contains('Monitors').click();
+ cy.get('a').contains('Monitors').click({ force: true });
// Confirm we can see the created monitor in the list
cy.contains(SAMPLE_CLUSTER_METRICS_HEALTH_MONITOR);
@@ -223,7 +225,7 @@ describe('ClusterMetricsMonitor', () => {
});
});
- describe('displays Query parameters field appropriately', () => {
+ describe('displays Path parameters field appropriately', () => {
beforeEach(() => {
cy.deleteAllMonitors();
cy.reload();
@@ -234,10 +236,12 @@ describe('ClusterMetricsMonitor', () => {
cy.contains('There are no existing monitors');
// Go to create monitor page
- cy.contains('Create monitor').click();
+ cy.contains('Create monitor', { timeout: 20000 }).click({ force: true });
// Select ClusterMetrics radio card
- cy.get('[data-test-subj="clusterMetricsMonitorRadioCard"]').click();
+ cy.get('[data-test-subj="clusterMetricsMonitorRadioCard"]').click({
+ force: true,
+ });
// Wait for input to load and then type in the monitor name
cy.get('input[name="name"]').type(
@@ -249,9 +253,9 @@ describe('ClusterMetricsMonitor', () => {
'list snapshots{enter}'
);
- // Confirm the Query parameters field is present and is not described as "optional"
- cy.contains('Query parameters - optional').should('not.exist');
- cy.contains('Query parameters');
+ // Confirm the Path parameters field is present and is not described as "optional"
+ cy.contains('Path parameters - optional').should('not.exist');
+ cy.contains('Path parameters');
cy.get('[data-test-subj="clusterMetricsParamsFieldText"]');
});
});
diff --git a/cypress/integration/plugins/alerting-dashboards-plugin/composite_level_monitor_spec.js b/cypress/integration/plugins/alerting-dashboards-plugin/composite_level_monitor_spec.js
new file mode 100644
index 000000000..fe1f47d87
--- /dev/null
+++ b/cypress/integration/plugins/alerting-dashboards-plugin/composite_level_monitor_spec.js
@@ -0,0 +1,191 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ ALERTING_API,
+ ALERTING_PLUGIN_NAME,
+} from '../../../utils/plugins/alerting-dashboards-plugin/constants';
+import sampleCompositeJson from '../../../fixtures/plugins/alerting-dashboards-plugin/sample_composite_level_monitor.json';
+import * as _ from 'lodash';
+import { BASE_PATH } from '../../../utils/base_constants';
+
+const sample_index_1 = 'sample_index_1';
+const sample_index_2 = 'sample_index_2';
+const SAMPLE_VISUAL_EDITOR_MONITOR =
+ 'sample_visual_editor_composite_level_monitor';
+
+const clearAll = () => {
+ cy.deleteIndexByName(sample_index_1);
+ cy.deleteIndexByName(sample_index_2);
+
+ cy.deleteAllAlerts();
+ cy.deleteAllMonitors();
+};
+
+describe('CompositeLevelMonitor', () => {
+ before(() => {
+ clearAll();
+
+ // Create indices
+ cy.createIndexByName(
+ sample_index_1,
+ sampleCompositeJson.sample_composite_index
+ );
+ cy.createIndexByName(
+ sample_index_2,
+ sampleCompositeJson.sample_composite_index
+ );
+
+ // Create associated monitors
+ cy.createMonitor(sampleCompositeJson.sample_composite_associated_monitor_1);
+ cy.createMonitor(sampleCompositeJson.sample_composite_associated_monitor_2);
+ cy.createMonitor(sampleCompositeJson.sample_composite_associated_monitor_3);
+ });
+
+ beforeEach(() => {
+ // Set welcome screen tracking to false
+ localStorage.setItem('home:welcome:show', 'false');
+ });
+
+ describe('can be created', () => {
+ beforeEach(() => {
+ // Visit Alerting OpenSearch Dashboards
+ cy.visit(`${BASE_PATH}/app/${ALERTING_PLUGIN_NAME}#/monitors`);
+
+ // Common text to wait for to confirm page loaded, give up to 20 seconds for initial load
+ cy.contains('Create monitor', { timeout: 20000 });
+
+ // Go to create monitor page
+ cy.contains('Create monitor').click({ force: true });
+
+ // Select the Composite-Level Monitor type
+ cy.get('[data-test-subj="compositeLevelMonitorRadioCard"]').click({
+ force: true,
+ });
+ });
+
+ it('by visual editor', () => {
+ // Select visual editor for method of definition
+ cy.get('[data-test-subj="visualEditorRadioCard"]').click({ force: true });
+
+ // Wait for input to load and then type in the monitor name
+ cy.get('input[name="name"]').type(SAMPLE_VISUAL_EDITOR_MONITOR);
+
+ // Select associated monitors
+ cy.get('[data-test-subj="monitors_list_0"]').type('monitorOne', {
+ delay: 50,
+ });
+ cy.get('[title="monitorOne"]').click({ force: true });
+
+ cy.get('[data-test-subj="monitors_list_1"]').type('monitorTwo', {
+ delay: 50,
+ });
+ cy.get('[title="monitorTwo"]').click({ force: true });
+
+ cy.get('button').contains('Add trigger').click({ force: true });
+
+ // Type trigger name
+ cy.get('[data-test-subj="composite-trigger-name"]')
+ .type('{selectall}')
+ .type('{backspace}')
+ .type('Composite trigger');
+
+ cy.intercept('api/alerting/workflows').as('createMonitorRequest');
+ cy.intercept(`api/alerting/monitors?*`).as('getMonitorsRequest');
+ cy.get('button').contains('Create').click({ force: true });
+
+ // Wait for monitor to be created
+ cy.wait('@createMonitorRequest').then(() => {
+ // Verify the monitor name on details page
+ cy.contains(SAMPLE_VISUAL_EDITOR_MONITOR);
+
+ // Go back to the Monitors list
+ cy.get('a').contains('Monitors').click({ force: true });
+
+ cy.contains(SAMPLE_VISUAL_EDITOR_MONITOR);
+ });
+ });
+ });
+
+ describe('can be edited', () => {
+ beforeEach(() => {
+ const body = {
+ size: 200,
+ query: {
+ match_all: {},
+ },
+ };
+ cy.request({
+ method: 'GET',
+ url: `${Cypress.env('openSearchUrl')}${
+ ALERTING_API.MONITOR_BASE
+ }/_search`,
+ failOnStatusCode: false, // In case there is no alerting config index in cluster, where the status code is 404
+ body,
+ }).then((response) => {
+ if (response.status === 200) {
+ const monitors = response.body.hits.hits;
+ const createdMonitor = _.find(
+ monitors,
+ (monitor) => monitor._source.name === SAMPLE_VISUAL_EDITOR_MONITOR
+ );
+ if (createdMonitor) {
+ cy.visit(
+ `${BASE_PATH}/app/${ALERTING_PLUGIN_NAME}#/monitors/${createdMonitor._id}?action=update-monitor&type=workflow`
+ );
+ } else {
+ cy.log(
+ 'Failed to get created monitor ',
+ SAMPLE_VISUAL_EDITOR_MONITOR
+ );
+ throw new Error(
+ `Failed to get created monitor ${SAMPLE_VISUAL_EDITOR_MONITOR}`
+ );
+ }
+ } else {
+ cy.log('Failed to get all monitors.', response);
+ }
+ });
+ });
+
+ it('by visual editor', () => {
+ // Verify edit page
+ cy.contains('Edit monitor', { timeout: 20000 });
+ cy.get('input[name="name"]').type('_edited');
+
+ cy.get('label').contains('Visual editor').click({ force: true });
+
+ cy.get('button').contains('Add another monitor').click({ force: true });
+
+ cy.get('[data-test-subj="monitors_list_2"]').type('monitorThree', {
+ delay: 50,
+ });
+ cy.get('[title="monitorThree"]').click({ force: true });
+
+ cy.get('button').contains('Composite trigger').click({ force: true });
+
+ cy.get('[data-test-subj="condition-add-options-btn_0"]').click({
+ force: true,
+ });
+ cy.get('[data-test-subj="select-expression_0_2"]').click({ force: true });
+ cy.wait(1000);
+ cy.get('[data-test-subj="monitors-combobox-0-2"]')
+ .type('monitorThree', { delay: 50 })
+ .type('{enter}');
+
+ cy.intercept('api/alerting/workflows/*').as('updateMonitorRequest');
+ cy.get('button').contains('Update').click({ force: true });
+
+ // Wait for monitor to be created
+ cy.wait('@updateMonitorRequest').then(() => {
+ cy.get('.euiTitle--large').contains(
+ `${SAMPLE_VISUAL_EDITOR_MONITOR}_edited`
+ );
+ });
+ });
+ });
+
+ after(() => clearAll());
+});
diff --git a/cypress/integration/plugins/alerting-dashboards-plugin/monitors_dashboard_spec.js b/cypress/integration/plugins/alerting-dashboards-plugin/monitors_dashboard_spec.js
new file mode 100644
index 000000000..ba8898ee6
--- /dev/null
+++ b/cypress/integration/plugins/alerting-dashboards-plugin/monitors_dashboard_spec.js
@@ -0,0 +1,152 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ ALERTING_INDEX,
+ ALERTING_PLUGIN_NAME,
+} from '../../../utils/plugins/alerting-dashboards-plugin/constants';
+import sampleAlertsFlyoutBucketMonitor from '../../../fixtures/plugins/alerting-dashboards-plugin/sample_alerts_flyout_bucket_level_monitor.json';
+import sampleAlertsFlyoutQueryMonitor from '../../../fixtures/plugins/alerting-dashboards-plugin/sample_alerts_flyout_query_level_monitor.json';
+import sampleClusterMetricsHealthMonitor from '../../../fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_health_monitor.json';
+import sampleClusterMetricsStatsMonitor from '../../../fixtures/plugins/alerting-dashboards-plugin/sample_cluster_metrics_stats_monitor.json';
+import { BASE_PATH } from '../../../utils/base_constants';
+
+const queryMonitor = {
+ ...sampleAlertsFlyoutQueryMonitor,
+ id: 'monitors_dashboard_cypress_query_level',
+ name: 'monitors_dashboard_cypress_query_level',
+ enabled: false,
+};
+const bucketMonitor = {
+ ...sampleAlertsFlyoutBucketMonitor,
+ id: 'monitors_dashboard_cypress_bucket_level',
+ name: 'monitors_dashboard_cypress_bucket_level',
+ enabled: false,
+};
+const clusterHealthMonitor = {
+ ...sampleClusterMetricsHealthMonitor,
+ id: 'monitors_dashboard_cypress_cluster_health',
+ name: 'monitors_dashboard_cypress_cluster_health',
+ enabled: false,
+ triggers: [
+ {
+ query_level_trigger: {
+ id: 'WJmlA4kBIezNcMbMwnFg',
+ name: 'sample_cluster_metrics_health_monitor-trigger1',
+ severity: '1',
+ condition: {
+ script: {
+ source: 'ctx.results[0].status != "green"',
+ lang: 'painless',
+ },
+ },
+ actions: [],
+ },
+ },
+ ],
+};
+const clusterStatsMonitor = {
+ ...sampleClusterMetricsStatsMonitor,
+ enabled: false,
+ id: 'monitors_dashboard_cypress_cluster_stats',
+ name: 'monitors_dashboard_cypress_cluster_stats',
+};
+const testMonitors = [
+ {
+ monitor: queryMonitor,
+ expectedAlertsCount: 1,
+ triggerName: queryMonitor.triggers[0].query_level_trigger.name,
+ },
+ {
+ monitor: bucketMonitor,
+ expectedAlertsCount: 46,
+ triggerName: bucketMonitor.triggers[0].bucket_level_trigger.name,
+ },
+ {
+ monitor: clusterHealthMonitor,
+ expectedAlertsCount: 1,
+ triggerName: clusterHealthMonitor.triggers[0].query_level_trigger.name,
+ },
+ {
+ monitor: clusterStatsMonitor,
+ expectedAlertsCount: 1,
+ triggerName: clusterStatsMonitor.triggers[0].query_level_trigger.name,
+ },
+];
+
+describe('Monitors dashboard page', () => {
+ before(() => {
+ // Delete any existing monitors
+ cy.deleteAllMonitors()
+ .then(() => {
+ // Load sample data
+ cy.loadSampleEcommerceData();
+ })
+ .then(() => {
+ // Short wait to reduce flakiness while ecommerce data is loaded
+ cy.wait(5000);
+
+ // Create the test monitors
+ testMonitors.forEach((entry) =>
+ cy.createAndExecuteMonitor(entry.monitor)
+ );
+ });
+
+ // Visit Alerting OpenSearch Dashboards
+ cy.visit(`${BASE_PATH}/app/${ALERTING_PLUGIN_NAME}#/monitors`);
+ });
+
+ beforeEach(() => {
+ // Refresh Alerting OpenSearch Dashboards
+ cy.visit(`${BASE_PATH}/app/${ALERTING_PLUGIN_NAME}#/monitors`);
+
+ // Common text to wait for to confirm page loaded, give up to 20 seconds for initial load
+ cy.contains('Create monitor', { timeout: 20000 });
+ });
+
+ it('Displays expected number of alerts', () => {
+ // Ensure the 'Monitor name' column is sorted in ascending order by sorting another column first
+ cy.contains('Last updated by').click({ force: true });
+ cy.contains('Monitor name').click({ force: true });
+
+ testMonitors.forEach((entry) => {
+ cy.get('tbody > tr')
+ .filter(`:contains(${entry.monitor.name})`, { timeout: 20000 })
+ .within(() => {
+ cy.get('[class="euiTableRowCell"]')
+ .filter(':contains(Latest alert)', { timeout: 20000 })
+ .should('contain', entry.triggerName);
+
+ cy.get('[class="euiTableRowCell"]')
+ .filter(':contains(State)', { timeout: 20000 })
+ .should('contain', 'Disabled');
+
+ cy.get('[class="euiTableRowCell"]')
+ .filter(':contains(Active)', { timeout: 20000 })
+ .should('contain', entry.expectedAlertsCount);
+
+ cy.get('[class="euiTableRowCell"]')
+ .filter(':contains(Acknowledged)', { timeout: 20000 })
+ .should('contain', 0);
+
+ cy.get('[class="euiTableRowCell"]')
+ .filter(':contains(Errors)', { timeout: 20000 })
+ .should('contain', 0);
+
+ cy.get('[class="euiTableRowCell"]')
+ .filter(':contains(Ignored)', { timeout: 20000 })
+ .should('contain', 0);
+ });
+ });
+ });
+
+ after(() => {
+ // Delete all monitors
+ cy.deleteAllMonitors();
+
+ // Delete sample data
+ cy.deleteIndexByName(ALERTING_INDEX.SAMPLE_DATA_ECOMMERCE);
+ });
+});
diff --git a/cypress/integration/plugins/alerting-dashboards-plugin/query_level_monitor_spec.js b/cypress/integration/plugins/alerting-dashboards-plugin/query_level_monitor_spec.js
index 9ff1aac74..5a7a9d858 100644
--- a/cypress/integration/plugins/alerting-dashboards-plugin/query_level_monitor_spec.js
+++ b/cypress/integration/plugins/alerting-dashboards-plugin/query_level_monitor_spec.js
@@ -34,7 +34,12 @@ const addVisualQueryLevelTrigger = (
thresholdValue
) => {
// Click 'Add trigger' button
- cy.contains('Add trigger', { timeout: 20000 }).click({ force: true });
+ if (triggerIndex === 0)
+ cy.contains('Add trigger', { timeout: 20000 }).click({ force: true });
+ else
+ cy.contains('Add another trigger', { timeout: 20000 }).click({
+ force: true,
+ });
if (isEdit) {
// TODO: Passing button props in EUI accordion was added in newer versions (31.7.0+).
@@ -244,6 +249,10 @@ describe('Query-Level Monitors', () => {
// Click the Delete button
cy.contains('Delete').click({ force: true });
+ cy.wait(1000);
+ cy.get('[data-test-subj="confirmModalConfirmButton"]').click({
+ force: true,
+ });
// Confirm we can see an empty monitor list
cy.contains('There are no existing monitors');
diff --git a/cypress/utils/plugins/alerting-dashboards-plugin/commands.js b/cypress/utils/plugins/alerting-dashboards-plugin/commands.js
index 962566271..c0a49307a 100644
--- a/cypress/utils/plugins/alerting-dashboards-plugin/commands.js
+++ b/cypress/utils/plugins/alerting-dashboards-plugin/commands.js
@@ -36,7 +36,7 @@ Cypress.Commands.add('createMonitor', (monitorJSON) => {
'POST',
`${Cypress.env('openSearchUrl')}${ALERTING_API.MONITOR_BASE}`,
monitorJSON
- );
+ ).then(({ body }) => body);
});
Cypress.Commands.add('createAndExecuteMonitor', (monitorJSON) => {
@@ -50,10 +50,43 @@ Cypress.Commands.add('createAndExecuteMonitor', (monitorJSON) => {
`${Cypress.env('openSearchUrl')}${ALERTING_API.MONITOR_BASE}/${
response.body._id
}/_execute`
- );
+ ).then(({ body }) => body);
});
});
+Cypress.Commands.add('executeMonitor', (monitorID) => {
+ cy.request(
+ 'POST',
+ `${Cypress.env('openSearchUrl')}${
+ ALERTING_API.MONITOR_BASE
+ }/${monitorID}/_execute`
+ ).then(({ body }) => body);
+});
+
+Cypress.Commands.add('executeCompositeMonitor', (monitorID) => {
+ cy.request(
+ 'POST',
+ `${Cypress.env('openSearchUrl')}${
+ ALERTING_API.WORKFLOW_BASE
+ }/${monitorID}/_execute`
+ ).then(({ body }) => body);
+});
+
+Cypress.Commands.add('deleteAllAlerts', () => {
+ cy.request({
+ method: 'POST',
+ url: `${Cypress.env(
+ 'openSearchUrl'
+ )}/.opendistro-alerting-alert*/_delete_by_query`,
+ body: {
+ query: {
+ match_all: {},
+ },
+ },
+ failOnStatusCode: false,
+ }).then(({ body }) => body);
+});
+
Cypress.Commands.add('deleteMonitorByName', (monitorName) => {
const body = {
query: {
@@ -75,7 +108,7 @@ Cypress.Commands.add('deleteMonitorByName', (monitorName) => {
`${Cypress.env('openSearchUrl')}${ALERTING_API.MONITOR_BASE}/${
response.body.hits.hits[0]._id
}`
- );
+ ).then(({ body }) => body);
});
});
@@ -83,9 +116,7 @@ Cypress.Commands.add('deleteAllMonitors', () => {
const body = {
size: 200,
query: {
- exists: {
- field: 'monitor',
- },
+ match_all: {},
},
};
cy.request({
@@ -95,13 +126,21 @@ Cypress.Commands.add('deleteAllMonitors', () => {
body,
}).then((response) => {
if (response.status === 200) {
- for (let i = 0; i < response.body.hits.total.value; i++) {
- cy.request(
- 'DELETE',
- `${Cypress.env('openSearchUrl')}${ALERTING_API.MONITOR_BASE}/${
- response.body.hits.hits[i]._id
- }`
- );
+ const monitors = response.body.hits.hits.sort((monitor) =>
+ monitor._source.type === 'workflow' ? -1 : 1
+ );
+ for (let i = 0; i < monitors.length; i++) {
+ if (monitors[i]._id) {
+ cy.request({
+ method: 'DELETE',
+ url: `${Cypress.env('openSearchUrl')}${
+ monitors[i]._source.type === 'workflow'
+ ? ALERTING_API.WORKFLOW_BASE
+ : ALERTING_API.MONITOR_BASE
+ }/${monitors[i]._id}`,
+ failOnStatusCode: false,
+ }).then(({ body }) => body);
+ }
}
} else {
cy.log('Failed to get all monitors.', response);
@@ -110,11 +149,17 @@ Cypress.Commands.add('deleteAllMonitors', () => {
});
Cypress.Commands.add('createIndexByName', (indexName) => {
- cy.request('PUT', `${Cypress.env('openSearchUrl')}/${indexName}`);
+ cy.request('PUT', `${Cypress.env('openSearchUrl')}/${indexName}`).then(
+ ({ body }) => body
+ );
});
Cypress.Commands.add('deleteIndexByName', (indexName) => {
- cy.request('DELETE', `${Cypress.env('openSearchUrl')}/${indexName}`);
+ cy.request({
+ method: 'DELETE',
+ url: `${Cypress.env('openSearchUrl')}/${indexName}`,
+ failOnStatusCode: false,
+ }).then(({ body }) => body);
});
Cypress.Commands.add(
@@ -124,7 +169,7 @@ Cypress.Commands.add(
'POST',
`${Cypress.env('openSearchUrl')}/${indexName}/_doc/${documentId}`,
documentBody
- );
+ ).then(({ body }) => body);
}
);
@@ -133,5 +178,5 @@ Cypress.Commands.add('loadSampleEcommerceData', () => {
method: 'POST',
headers: { 'osd-xsrf': 'opensearch-dashboards' },
url: `${BASE_PATH}/api/sample_data/ecommerce`,
- });
+ }).then(({ body }) => body);
});
diff --git a/cypress/utils/plugins/alerting-dashboards-plugin/constants.js b/cypress/utils/plugins/alerting-dashboards-plugin/constants.js
index f4a1aad82..f2df921ac 100644
--- a/cypress/utils/plugins/alerting-dashboards-plugin/constants.js
+++ b/cypress/utils/plugins/alerting-dashboards-plugin/constants.js
@@ -12,6 +12,7 @@ export const ALERTING_INDEX = {
export const ALERTING_API = {
MONITOR_BASE: `${API_ROUTE_PREFIX}/monitors`,
+ WORKFLOW_BASE: `${API_ROUTE_PREFIX}/workflows`,
DESTINATION_BASE: `${API_ROUTE_PREFIX}/destinations`,
};