-
Notifications
You must be signed in to change notification settings - Fork 131
[VisBuilder-Next] Migrate legacy visualizations to visbuilder by mapping the url #1533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
96c3caf
94aef66
f0a82c0
2054b2c
206481a
5c89d4b
4828655
49e5ce3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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":[]} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to do a clean up after step? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @LDrago27, i forget what was the suggestion with delete and insert? is this safe for runs with frequent write/deletes? |
||
| 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 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. potential action item: does euiBasicTable-loading have a test id in the page we use it? if not we could probably add one. |
||
| 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'); | ||
| }); | ||
| }); | ||
| }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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'; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: should this go under
|
||
| 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}`; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: do we think we should prepend
legacy_or something that gives more details sometimes in the future i imagine myself forgetting why we have two ndjson files in this folder and will help me distinguish the two without reading the test.not a blocker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the other ndjson file is named
vb_saved_objects.ndjson, which helps distinguish two files?visualization_saved_objects.ndjsonis for legacy andvb_saved_objects.ndjsonis for visbuilder