From 2d77889abf2a24c0ca597adcef8cd687927f2799 Mon Sep 17 00:00:00 2001
From: Hailong Cui <ihailong@amazon.com>
Date: Wed, 13 Nov 2024 15:04:39 +0800
Subject: [PATCH] Add cypress test for workspace overview page (#1633)

* cypress test for use case overview page

Signed-off-by: Hailong Cui <ihailong@amazon.com>

* add cypress test for analytics overview page

Signed-off-by: Hailong Cui <ihailong@amazon.com>

* add sample data cleanup

Signed-off-by: Hailong Cui <ihailong@amazon.com>

* support mds is not enabled

Signed-off-by: Hailong Cui <ihailong@amazon.com>

* remove alerts cards

Signed-off-by: Hailong Cui <ihailong@amazon.com>

* fix failed test case

Signed-off-by: Hailong Cui <ihailong@amazon.com>

---------

Signed-off-by: Hailong Cui <ihailong@amazon.com>
(cherry picked from commit 295636cbd19ae166cc06c1acde1c724cae6af62f)
---
 .../mds_workspace_analytics_overviews.spec.js | 151 +++++++++++++++++
 .../mds_workspace_essential_overviews.spec.js | 153 ++++++++++++++++++
 .../mds_workspace_search_overviews.spec.js    |  92 +++++++++++
 cypress/utils/commands.js                     |  26 +++
 4 files changed, 422 insertions(+)
 create mode 100644 cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_analytics_overviews.spec.js
 create mode 100644 cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_essential_overviews.spec.js
 create mode 100644 cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_search_overviews.spec.js

diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_analytics_overviews.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_analytics_overviews.spec.js
new file mode 100644
index 000000000..2f8241a74
--- /dev/null
+++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_analytics_overviews.spec.js
@@ -0,0 +1,151 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { MiscUtils } from '@opensearch-dashboards-test/opensearch-dashboards-test-library';
+
+const miscUtils = new MiscUtils(cy);
+const workspaceName = `test_workspace_analytics_${Math.random()
+  .toString(36)
+  .substring(7)}`;
+let workspaceDescription = 'This is a analytics workspace description.';
+let workspaceId;
+let datasourceId;
+let workspaceFeatures = ['use-case-all'];
+
+const MDSEnabled = Cypress.env('DATASOURCE_MANAGEMENT_ENABLED');
+
+if (Cypress.env('WORKSPACE_ENABLED')) {
+  const createWorkspace = (dsId) => {
+    cy.createWorkspace({
+      name: workspaceName,
+      description: workspaceDescription,
+      features: workspaceFeatures,
+      settings: {
+        permissions: {
+          library_write: { users: ['%me%'] },
+          write: { users: ['%me%'] },
+        },
+        ...(dsId ? { dataSources: [dsId] } : {}),
+      },
+    }).then((value) => {
+      workspaceId = value;
+      // load sample data
+      cy.loadSampleDataForWorkspace('ecommerce', value, dsId);
+    });
+  };
+
+  describe('Analytics workspace overview', () => {
+    before(() => {
+      cy.deleteWorkspaceByName(workspaceName);
+      if (MDSEnabled) {
+        cy.deleteAllDataSources();
+        cy.createDataSourceNoAuth().then((result) => {
+          datasourceId = result[0];
+          expect(datasourceId).to.be.a('string').that.is.not.empty;
+          createWorkspace(datasourceId);
+        });
+      } else {
+        createWorkspace();
+      }
+    });
+
+    after(() => {
+      if (workspaceId) {
+        cy.removeSampleDataForWorkspace('ecommerce', workspaceId, datasourceId);
+        cy.deleteWorkspaceById(workspaceId);
+      }
+      cy.deleteAllDataSources();
+    });
+
+    beforeEach(() => {
+      // Visit workspace update page
+      miscUtils.visitPage(`w/${workspaceId}/app/all_overview`);
+      // wait for page load
+      cy.contains('h1', 'Overview');
+    });
+
+    it('should display get started sections', () => {
+      cy.get('.euiCard__footer').contains('Observability').should('be.visible');
+      // this is depends on observability plugin been installed
+      // cy.url().should('include', 'app/observability-overview');
+
+      cy.get('.euiCard__footer')
+        .contains('Security Analytics')
+        .should('be.visible');
+      // this is depends on security analytics plugin been installed
+      // cy.url().should('include', 'app/sa_overview');
+
+      cy.get('.euiCard__footer')
+        .contains('Search')
+        .should('be.visible')
+        .click();
+      cy.url().should('include', 'app/search_overview');
+    });
+
+    it('should display asset section correctly', () => {
+      // no recently view assets
+      cy.contains('No assets to display');
+
+      // recentlyCard
+      cy.contains('Recently updated').should('be.visible').click();
+      // should have 6 elements
+      cy.getElementByTestId('recentlyCard').should('have.length', 6);
+
+      // filter by dashboard
+      cy.getElementByTestId('comboBoxInput').click();
+      cy.get('span.euiComboBoxOption__content').contains('dashboard').click();
+
+      // click dashboard card
+      cy.getElementByTestId('recentlyCard').first().click();
+
+      // verify url has /app/dashboards
+      cy.url().should('include', 'app/dashboards');
+
+      cy.go('back');
+
+      // view all
+      cy.contains('View all').click();
+      // verify url has /app/objects
+      cy.url().should('include', 'app/objects');
+    });
+
+    // Alerts and threat Alerts cards are depends on plugins
+
+    it('should display OpenSearch Documentation panel', () => {
+      cy.contains('OpenSearch Documentation').should('be.visible');
+      cy.get('.euiLink')
+        .contains('Quickstart guide')
+        .should('be.visible')
+        .and(
+          'have.attr',
+          'href',
+          'https://opensearch.org/docs/latest/dashboards/quickstart/'
+        );
+      cy.get('.euiLink')
+        .contains('Building data visualizations')
+        .should('be.visible')
+        .and(
+          'have.attr',
+          'href',
+          'https://opensearch.org/docs/latest/dashboards/visualize/viz-index/'
+        );
+      cy.get('.euiLink')
+        .contains('Creating dashboards')
+        .should('be.visible')
+        .and(
+          'have.attr',
+          'href',
+          'https://opensearch.org/docs/latest/dashboards/dashboard/index/'
+        );
+      cy.contains('Learn more in Documentation')
+        .should('be.visible')
+        .and(
+          'have.attr',
+          'href',
+          'https://opensearch.org/docs/latest/dashboards/index/'
+        );
+    });
+  });
+}
diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_essential_overviews.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_essential_overviews.spec.js
new file mode 100644
index 000000000..8d24abaf6
--- /dev/null
+++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_essential_overviews.spec.js
@@ -0,0 +1,153 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { MiscUtils } from '@opensearch-dashboards-test/opensearch-dashboards-test-library';
+
+const miscUtils = new MiscUtils(cy);
+const workspaceName = `test_workspace_${Math.random()
+  .toString(36)
+  .substring(7)}`;
+let workspaceDescription = 'This is a workspace description.';
+let workspaceId;
+let datasourceId;
+let workspaceFeatures = ['use-case-essentials'];
+
+const MDSEnabled = Cypress.env('DATASOURCE_MANAGEMENT_ENABLED');
+
+if (Cypress.env('WORKSPACE_ENABLED')) {
+  const createWorkspace = (datasourceId) => {
+    cy.createWorkspace({
+      name: workspaceName,
+      description: workspaceDescription,
+      features: workspaceFeatures,
+      settings: {
+        permissions: {
+          library_write: { users: ['%me%'] },
+          write: { users: ['%me%'] },
+        },
+        ...(datasourceId ? { dataSources: [datasourceId] } : {}),
+      },
+    }).then((value) => {
+      workspaceId = value;
+      // load sample data
+      cy.loadSampleDataForWorkspace('ecommerce', value, datasourceId);
+    });
+  };
+
+  describe('Essential workspace overview', () => {
+    before(() => {
+      cy.deleteWorkspaceByName(workspaceName);
+      if (MDSEnabled) {
+        cy.deleteAllDataSources();
+        cy.createDataSourceNoAuth().then((result) => {
+          datasourceId = result[0];
+          expect(datasourceId).to.be.a('string').that.is.not.empty;
+          createWorkspace(datasourceId);
+        });
+      } else {
+        createWorkspace();
+      }
+    });
+
+    after(() => {
+      if (workspaceId) {
+        cy.removeSampleDataForWorkspace('ecommerce', workspaceId, datasourceId);
+        cy.deleteWorkspaceById(workspaceId);
+      }
+      cy.deleteAllDataSources();
+    });
+
+    beforeEach(() => {
+      // Visit workspace update page
+      miscUtils.visitPage(`w/${workspaceId}/app/essentials_overview`);
+      // wait for page load
+      cy.contains('h1', 'Overview');
+    });
+
+    it('Get started cards display correctly', () => {
+      // verify four get started cards exist
+      cy.contains('Install sample data to experiment with OpenSearch.').click();
+      // verify url has app/import_sample_data
+      cy.url().should('include', 'app/import_sample_data');
+
+      // browser back
+      cy.go('back');
+      cy.contains('Explore data to uncover and discover insights.').click();
+      // verify url has app/data-explorer/discover
+      cy.url().should('include', 'app/data-explorer/discover');
+
+      // browser back
+      cy.go('back');
+      cy.contains(
+        'Gain deeper insights by visualizing and aggregating your data.'
+      ).click();
+      // verify url has app/visualize
+      cy.url().should('include', 'app/visualize');
+
+      cy.go('back');
+      cy.contains(
+        'Monitor and explore your data using dynamic data visualization tools.'
+      ).click();
+      // verify url has app/dashboards
+      cy.url().should('include', 'app/dashboards');
+    });
+
+    it('Assets cards display correctly', () => {
+      // no recently view assets
+      cy.contains('No assets to display');
+
+      // recentlyCard
+      cy.contains('Recently updated').should('be.visible').click();
+      // should have 6 elements
+      cy.getElementByTestId('recentlyCard').should('have.length', 6);
+
+      // filter by dashboard
+      cy.getElementByTestId('comboBoxInput').click();
+      cy.get('span.euiComboBoxOption__content').contains('dashboard').click();
+
+      // click dashboard card
+      cy.getElementByTestId('recentlyCard').first().click();
+
+      // verify url has /app/dashboards
+      cy.url().should('include', 'app/dashboards');
+
+      cy.go('back');
+
+      // view all
+      cy.contains('View all').click();
+      // verify url has /app/objects
+      cy.url().should('include', 'app/objects');
+    });
+
+    it('Opensearch documentation cards display correctly', () => {
+      cy.contains('OpenSearch Documentation');
+
+      // get a link with text as Quickstart guide
+      cy.get('a')
+        .contains('Quickstart guide')
+        .should(
+          'have.attr',
+          'href',
+          'https://opensearch.org/docs/latest/dashboards/quickstart/'
+        );
+
+      cy.get('a')
+        .contains('Building data visualizations')
+        .should(
+          'have.attr',
+          'href',
+          'https://opensearch.org/docs/latest/dashboards/visualize/viz-index/'
+        );
+
+      cy.get('a')
+        .contains('Creating dashboards')
+        .should(
+          'have.attr',
+          'href',
+          'https://opensearch.org/docs/latest/dashboards/dashboard/index/'
+        );
+    });
+  });
+}
diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_search_overviews.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_search_overviews.spec.js
new file mode 100644
index 000000000..8199eba07
--- /dev/null
+++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/workspace-plugin/mds_workspace_search_overviews.spec.js
@@ -0,0 +1,92 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { MiscUtils } from '@opensearch-dashboards-test/opensearch-dashboards-test-library';
+
+const miscUtils = new MiscUtils(cy);
+const workspaceName = `test_workspace_search_${Math.random()
+  .toString(36)
+  .substring(7)}`;
+let workspaceDescription = 'This is a  search workspace description.';
+let workspaceId;
+let datasourceId;
+let workspaceFeatures = ['use-case-search'];
+
+const MDSEnabled = Cypress.env('DATASOURCE_MANAGEMENT_ENABLED');
+
+if (Cypress.env('WORKSPACE_ENABLED')) {
+  const createWorkspace = (datasourceId) => {
+    cy.createWorkspace({
+      name: workspaceName,
+      description: workspaceDescription,
+      features: workspaceFeatures,
+      settings: {
+        permissions: {
+          library_write: { users: ['%me%'] },
+          write: { users: ['%me%'] },
+        },
+        ...(datasourceId ? { dataSources: [datasourceId] } : {}),
+      },
+    }).then((value) => {
+      workspaceId = value;
+    });
+  };
+
+  describe('Search workspace overview', () => {
+    before(() => {
+      cy.deleteWorkspaceByName(workspaceName);
+      if (MDSEnabled) {
+        cy.deleteAllDataSources();
+        cy.createDataSourceNoAuth().then((result) => {
+          datasourceId = result[0];
+          expect(datasourceId).to.be.a('string').that.is.not.empty;
+          createWorkspace(datasourceId);
+        });
+      } else {
+        createWorkspace();
+      }
+    });
+
+    after(() => {
+      if (workspaceId) {
+        cy.deleteWorkspaceById(workspaceId);
+      }
+      cy.deleteAllDataSources();
+    });
+
+    beforeEach(() => {
+      // Visit workspace update page
+      miscUtils.visitPage(`w/${workspaceId}/app/search_overview`);
+      // wait for page load
+      cy.contains('h1', 'Overview');
+    });
+
+    it('Set up search cards display correctly', () => {
+      cy.contains(
+        'Explore search capabilities and functionality of OpenSearch.'
+      );
+      cy.contains(
+        'Create a document collection (an index) to query your data.'
+      );
+
+      cy.contains('Explore data to uncover and discover insights.').click();
+      // verify url has app/data-explorer/discover
+      cy.url().should('include', 'app/data-explorer/discover');
+    });
+
+    it('Different search techniques section display correctly', () => {
+      cy.contains('h3', 'Text search').should('be.visible');
+      cy.contains('h3', 'Analyzers').should('be.visible');
+      cy.contains('h3', 'Semantic vector search').should('be.visible');
+      cy.contains('h3', 'Neural sparse search').should('be.visible');
+      cy.contains('h3', 'Hybrid search').should('be.visible');
+    });
+
+    it('Configure and evaluate search cards display correctly', () => {
+      cy.contains('Compare search results').should('be.visible').click();
+      cy.url().should('contains', 'app/searchRelevance');
+    });
+  });
+}
diff --git a/cypress/utils/commands.js b/cypress/utils/commands.js
index f74983fa3..3652172d5 100644
--- a/cypress/utils/commands.js
+++ b/cypress/utils/commands.js
@@ -572,6 +572,32 @@ Cypress.Commands.add('loadSampleData', (type) => {
   });
 });
 
+Cypress.Commands.add(
+  'loadSampleDataForWorkspace',
+  (type, workspaceId, datasourceId) => {
+    cy.request({
+      method: 'POST',
+      headers: { 'osd-xsrf': 'opensearch-dashboards' },
+      url: `${BASE_PATH}/w/${workspaceId}/api/sample_data/${type}?data_source_id=${
+        datasourceId || ''
+      }`,
+    });
+  }
+);
+
+Cypress.Commands.add(
+  'removeSampleDataForWorkspace',
+  (type, workspaceId, datasourceId) => {
+    cy.request({
+      method: 'DELETE',
+      headers: { 'osd-xsrf': 'opensearch-dashboards' },
+      url: `${BASE_PATH}/w/${workspaceId}/api/sample_data/${type}?data_source_id=${
+        datasourceId || ''
+      }`,
+    });
+  }
+);
+
 Cypress.Commands.add('fleshTenantSettings', () => {
   if (Cypress.env('SECURITY_ENABLED')) {
     // Use xhr request is good enough to flesh tenant