diff --git a/cypress/fixtures/dashboard/opensearch_dashboards/visBuilder/visualization_saved_objects.ndjson b/cypress/fixtures/dashboard/opensearch_dashboards/visBuilder/visualization_saved_objects.ndjson new file mode 100644 index 000000000..3546b6349 --- /dev/null +++ b/cypress/fixtures/dashboard/opensearch_dashboards/visBuilder/visualization_saved_objects.ndjson @@ -0,0 +1,4 @@ +{"attributes":{"fields":"[{\"count\":0,\"name\":\"_id\",\"type\":\"string\",\"esTypes\":[\"_id\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_index\",\"type\":\"string\",\"esTypes\":[\"_index\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_score\",\"type\":\"number\",\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_source\",\"type\":\"_source\",\"esTypes\":[\"_source\"],\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_type\",\"type\":\"string\",\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"age\",\"type\":\"number\",\"esTypes\":[\"long\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"avatar\",\"type\":\"string\",\"esTypes\":[\"text\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"avatar.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"avatar\"}}},{\"count\":0,\"name\":\"birthdate\",\"type\":\"date\",\"esTypes\":[\"date\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"categories\",\"type\":\"string\",\"esTypes\":[\"text\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"categories.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"categories\"}}},{\"count\":0,\"name\":\"email\",\"type\":\"string\",\"esTypes\":[\"text\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"email.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"email\"}}},{\"count\":0,\"name\":\"password\",\"type\":\"string\",\"esTypes\":[\"text\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"password.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"password\"}}},{\"count\":0,\"name\":\"salary\",\"type\":\"number\",\"esTypes\":[\"long\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"timestamp\",\"type\":\"date\",\"esTypes\":[\"date\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"userId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"userId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userId\"}}},{\"count\":0,\"name\":\"username\",\"type\":\"string\",\"esTypes\":[\"text\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"username.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"username\"}}}]","timeFieldName":"timestamp","title":"vis-builder"},"id":"a031e530-5a88-11ed-a595-f5e6ea9b3826","migrationVersion":{"index-pattern":"7.6.0"},"references":[],"type":"index-pattern","updated_at":"2022-11-02T08:30:36.803Z","version":"WzM3MCwxXQ=="} +{"attributes":{"description":"Visualization Builder: Basic Metric Chart","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"},"styleState":"{\"addTooltip\":true,\"addLegend\":false,\"type\":\"metric\",\"metric\":{\"percentageMode\":false,\"useRanges\":false,\"colorSchema\":\"Green to Red\",\"metricColorMode\":\"None\",\"colorsRange\":[{\"from\":0,\"to\":10000}],\"labels\":{\"show\":true},\"invertColors\":false,\"style\":{\"bgFill\":\"#000\",\"bgColor\":false,\"labelColor\":false,\"subText\":\"\",\"fontSize\":60}}}","title":"VB: Basic Metric Chart","version":2,"visualizationState":"{\"searchField\":\"\",\"activeVisualization\":{\"name\":\"metric\",\"aggConfigParams\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"params\":{},\"schema\":\"metric\"}]}}"},"id":"7050aba0-5a72-11ed-a595-f5e6ea9b3826","references":[{"id":"a031e530-5a88-11ed-a595-f5e6ea9b3826","name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern"}],"type":"visualization-visbuilder","updated_at":"2022-11-02T05:51:47.546Z","version":"WzI3LDFd"} +{"type":"visualization","id":"a9170530-593d-11ef-abf7-4174d431b442","attributes":{"title":"line-1","visState":"{\"title\":\"line-1\",\"type\":\"line\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"params\":{},\"schema\":\"metric\"},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"params\":{\"field\":\"timestamp\",\"timeRange\":{\"from\":\"now-15m\",\"to\":\"now\"},\"useNormalizedOpenSearchInterval\":true,\"scaleMetricValues\":false,\"interval\":\"d\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}},\"schema\":\"segment\"},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"params\":{\"field\":\"age\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":5,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"},\"schema\":\"group\"},{\"id\":\"4\",\"enabled\":true,\"type\":\"terms\",\"params\":{\"field\":\"categories.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":5,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"},\"schema\":\"split\"},{\"id\":\"5\",\"enabled\":true,\"type\":\"avg\",\"params\":{\"field\":\"salary\"},\"schema\":\"radius\"}],\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":false,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"filter\":true,\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"category\"}],\"grid\":{\"categoryLines\":false},\"labels\":{},\"legendPosition\":\"left\",\"row\":false,\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Count\"},\"drawLinesBetweenPoints\":true,\"interpolate\":\"linear\",\"lineWidth\":2,\"mode\":\"normal\",\"show\":true,\"showCircles\":true,\"type\":\"line\",\"valueAxis\":\"ValueAxis-1\"}],\"thresholdLine\":{\"color\":\"#E7664C\",\"show\":false,\"style\":\"full\",\"value\":10,\"width\":1},\"times\":[],\"type\":\"line\",\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"Count\"},\"type\":\"value\"}],\"radiusRatio\":35}}","uiStateJSON":"{}","description":"","version":1,"kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"27\",\"language\":\"kuery\"},\"filter\":[{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":null,\"disabled\":false,\"key\":\"age\",\"negate\":false,\"params\":{\"gte\":20,\"lt\":30},\"type\":\"range\",\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"range\":{\"age\":{\"gte\":20,\"lt\":30}}}],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"}},"references":[{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"a031e530-5a88-11ed-a595-f5e6ea9b3826"},{"name":"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index","type":"index-pattern","id":"a031e530-5a88-11ed-a595-f5e6ea9b3826"}],"migrationVersion":{"visualization":"7.10.0"},"updated_at":"2024-08-13T21:39:46.008Z","version":"WzIyMCwxXQ==","namespaces":["default"]} +{"exportedCount":1,"missingRefCount":0,"missingReferences":[]} \ No newline at end of file diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/vis_builder/migration.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/vis_builder/migration.spec.js new file mode 100644 index 000000000..c03f64bb6 --- /dev/null +++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/vis_builder/migration.spec.js @@ -0,0 +1,220 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + BASE_PATH, + toTestId, + VB_APP_PATH, + VB_INDEX_ID, + VB_METRIC_VIS_TITLE, + VB_PATH_INDEX_DATA, + VISUALIZATION_PATH_SO_DATA, +} from '../../../../../utils/constants'; +import { CURRENT_TENANT } from '../../../../../utils/commands'; + +if (Cypress.env('VISBUILDER_ENABLED')) { + describe('Vis Builder: Metric Chart', () => { + before(() => { + CURRENT_TENANT.newTenant = 'global'; + cy.fleshTenantSettings(); + cy.deleteIndex(VB_INDEX_ID); + cy.bulkUploadDocs(VB_PATH_INDEX_DATA); + cy.importSavedObjects(VISUALIZATION_PATH_SO_DATA); + }); + + beforeEach(() => { + CURRENT_TENANT.newTenant = 'global'; + cy.fleshTenantSettings(); + }); + + it('Show existing visualizations in Visualize and navigate to it', () => { + cy.visit(`${BASE_PATH}/app/visualize`); + cy.get('input[type="search"]').type(`${VB_METRIC_VIS_TITLE}{enter}`); + cy.get('.euiBasicTable-loading').should('not.exist'); // wait for the loading to stop + cy.getElementByTestId( + `visListingTitleLink-${toTestId(VB_METRIC_VIS_TITLE)}` + ) + .should('exist') + .click(); + cy.location('pathname').should('contain', VB_APP_PATH); + }); + + it('Should click pencil icon for Visbuilder object and check for absence of "Import to Visbuilder" option', () => { + cy.visit(`${BASE_PATH}/app/visualize`); + + cy.get('input[type="search"]').type(`${VB_METRIC_VIS_TITLE}{enter}`); + cy.get('.euiBasicTable-loading').should('not.exist'); + + // Find the specific row for the Visbuilder object + cy.contains('tr', 'VB: Basic Metric Chart').within(() => { + // Click the pencil icon using the test id "dashboardEditBtn" + cy.getElementByTestId('dashboardEditBtn').click(); + }); + + // Check that the popover does not contain "Import to Visbuilder" option + cy.get('.euiPopover__panel').should('be.visible'); + cy.contains('Import to VisBuilder').should('not.exist'); + }); + + it('Should click pencil icon for Line Chart and find "Import to Visbuilder" option', () => { + cy.visit(`${BASE_PATH}/app/visualize`); + + // Search for the line chart visualization + cy.get('input[type="search"]').clear().type('line-1{enter}'); + cy.get('.euiBasicTable-loading').should('not.exist'); + + // Find the specific row for the Line Chart object + cy.contains('tr', 'line-1').within(() => { + // Click the pencil icon using the test id "dashboardEditBtn" + cy.getElementByTestId('dashboardEditBtn').click(); + }); + + // Check that the popover contains "Import to Visbuilder" option + cy.get('.euiPopover__panel').should('be.visible'); + cy.contains('Import to VisBuilder').should('exist'); + }); + + it('Should import Line Chart to Visbuilder and verify breadcrumb', () => { + cy.visit(`${BASE_PATH}/app/visualize`); + + // Search for the line chart visualization + cy.get('input[type="search"]').clear().type('line-1{enter}'); + cy.get('.euiBasicTable-loading').should('not.exist'); + + // Find the specific row for the Line Chart object + cy.contains('tr', 'line-1').within(() => { + // Click the pencil icon using the test id "dashboardEditBtn" + cy.getElementByTestId('dashboardEditBtn').click(); + }); + + // Click the "Import to Visbuilder" button using its specific data test subject + cy.getElementByTestId('dashboardImportToVisBuilder').click(); + + cy.getElementByTestId('confirmModalConfirmButton').click(); + + // Check the last breadcrumb + cy.getElementByTestId('breadcrumb last').should( + 'contain', + 'New visualization' + ); + }); + + it('verify Save button is clickable and saves the visualization', () => { + cy.visit(`${BASE_PATH}/app/visualize`); + + // Search for the line chart visualization + cy.get('input[type="search"]').clear().type('line-1{enter}'); + cy.get('.euiBasicTable-loading').should('not.exist'); + + // Find the specific row for the Line Chart object + cy.contains('tr', 'line-1').within(() => { + // Click the pencil icon using the test id "dashboardEditBtn" + cy.getElementByTestId('dashboardEditBtn').click(); + }); + + // Click the "Import to Visbuilder" button using its specific data test subject + cy.getElementByTestId('dashboardImportToVisBuilder').click(); + + cy.getElementByTestId('confirmModalConfirmButton').click(); + + // Find the Save button and click it + cy.getElementByTestId('visBuilderSaveButton').click(); + + // Verify that clicking the Save button causes a popup to appear + cy.getElementByTestId('savedObjectSaveModal').should('be.visible'); + + cy.get('input[type="text"]').clear().type('test1'); + + // Find the Save button in the modal and click it + cy.getElementByTestId('confirmSaveSavedObjectButton').click(); + + // Verify that the visualization is saved by checking for the success message + cy.getElementByTestId('globalToastList') + .should('be.visible') + .and('contain', 'Saved'); + }); + + it('should import line chart to Visbuilder and verify filters, queries, and aggregations', () => { + cy.visit(`${BASE_PATH}/app/visualize`); + + // Search for the line chart visualization + cy.get('input[type="search"]').clear().type('line-1{enter}'); + cy.get('.euiBasicTable-loading').should('not.exist'); + + // Find the specific row for the Line Chart object + cy.contains('tr', 'line-1').within(() => { + // Click the pencil icon using the test id "dashboardEditBtn" + cy.getElementByTestId('dashboardEditBtn').click(); + }); + + // Click the "Import to Visbuilder" button using its specific data test subject + cy.getElementByTestId('dashboardImportToVisBuilder').click(); + + cy.getElementByTestId('confirmModalConfirmButton').click(); + + // Locate the global query bar first + cy.getElementByTestId('globalQueryBar').should('exist'); + + // Then, verify the presence of the specific specific query input + cy.getElementByTestId('queryInput') + .should('exist') + .and('contain.value', '27'); + + // verify filter + cy.get('[aria-label="Filter actions"]') + .should('exist') + .and( + 'have.attr', + 'title', + 'Filter: age: 20 to 30. Select for more filter actions.' + ); + + // verify chart type + cy.get('.vbSidenav__header') + .should('exist') + .within(() => { + cy.get('.euiPopover__anchor') + .should('exist') + .find('input') + .should('have.value', 'line'); + }); + + // verify Settings (Legend Position) + cy.get('.euiFormControlLayout__childrenWrapper') + .should('exist') + .and('contain.text', 'Left'); + + // verify configurations + cy.get('.vbConfig__section') + .should('exist') + .within(() => { + // Search for the dropBoxField-metric-0 data test subject and check if it contains "Count" + cy.get('[data-test-subj="dropBoxField-metric-0"]') + .should('exist') + .and('contain.text', 'Count'); + + // Search for the dropBoxField-segment-0 data test subject and check if it contains "timestamp per day" + cy.get('[data-test-subj="dropBoxField-segment-0"]') + .should('exist') + .and('contain.text', 'timestamp per day'); + + // Search for the dropBoxField-group-0 data test subject and check if it contains "age: Descending" + cy.get('[data-test-subj="dropBoxField-group-0"]') + .should('exist') + .and('contain.text', 'age: Descending'); + + // Search for the dropBoxField-split-0 data test subject and check if it contains "categories.keyword: Descending" + cy.get('[data-test-subj="dropBoxField-split-0"]') + .should('exist') + .and('contain.text', 'categories.keyword: Descending'); + + // Search for the dropBoxField-radius-0 data test subject and check if it contains "Average salary" + cy.get('[data-test-subj="dropBoxField-radius-0"]') + .should('exist') + .and('contain.text', 'Average salary'); + }); + }); + }); +} diff --git a/cypress/utils/dashboards/vis_builder/constants.js b/cypress/utils/dashboards/vis_builder/constants.js index 128eff374..ccb5e48e7 100644 --- a/cypress/utils/dashboards/vis_builder/constants.js +++ b/cypress/utils/dashboards/vis_builder/constants.js @@ -27,7 +27,14 @@ export const VB_PATH_FIXTURE = 'dashboard/opensearch_dashboards/visBuilder/'; export const VB_PATH_INDEX_DATA = VB_PATH_FIXTURE + VB_INDEX_DATA; export const VB_PATH_SO_DATA = VB_PATH_FIXTURE + VB_SO_DATA; +export const VISUALIZATION_SO_DATA = 'visualization_saved_objects.ndjson'; +export const VISUALIZATION_PATH_SO_DATA = + VB_PATH_FIXTURE + VISUALIZATION_SO_DATA; + // App URL Paths +export const VISUALIZE_APP_PATH = '/app/visualize'; +export const VISUALIZE_APP_URL = `${BASE_PATH}${VISUALIZE_APP_PATH}`; + export const VB_APP_PATH = '/app/vis-builder'; export const VB_APP_URL = `${BASE_PATH}${VB_APP_PATH}`;