From 2fe68a36331b341888d9d7f54300e27c81f77a46 Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Fri, 21 Oct 2022 15:10:35 +0300 Subject: [PATCH] chore: E2E Dashboards Cross-references (#21805) --- .../cypress-base/cypress/fixtures/charts.json | 20 ++-- .../cypress/fixtures/dashboards.json | 28 +++++ .../integration/chart_list/list.test.ts | 67 ++++++++++- .../integration/dashboard/actions.test.js | 2 +- .../integration/dashboard/editmode.test.ts | 6 +- .../dashboard/nativeFilters.test.ts | 6 +- .../integration/dashboard_list/list.test.ts | 2 +- .../cypress/integration/explore/chart.test.js | 106 ++++++++++++++++++ .../cypress/integration/explore/utils.ts | 20 ++++ .../src/components/ListView/CrossLinks.tsx | 2 +- .../components/MetadataBar/MetadataBar.tsx | 2 +- 11 files changed, 239 insertions(+), 22 deletions(-) diff --git a/superset-frontend/cypress-base/cypress/fixtures/charts.json b/superset-frontend/cypress-base/cypress/fixtures/charts.json index 6b342ee9a5..5781fce81e 100644 --- a/superset-frontend/cypress-base/cypress/fixtures/charts.json +++ b/superset-frontend/cypress-base/cypress/fixtures/charts.json @@ -5,8 +5,9 @@ "owners": [1], "viz_type": "line", "cache_timeout": 1000, - "datasource_id": 1, - "datasource_type": "table" + "datasource_id": 2, + "datasource_type": "table", + "params": "{\"viz_type\":\"line\",\"metrics\":[\"count\"]}" }, { "slice_name": "2 - Sample chart", @@ -14,8 +15,9 @@ "owners": [1], "viz_type": "line", "cache_timeout": 1000, - "datasource_id": 1, - "datasource_type": "table" + "datasource_id": 2, + "datasource_type": "table", + "params": "{\"viz_type\":\"line\",\"metrics\":[\"count\"]}" }, { "slice_name": "3 - Sample chart", @@ -23,8 +25,9 @@ "owners": [1], "viz_type": "line", "cache_timeout": 1000, - "datasource_id": 1, - "datasource_type": "table" + "datasource_id": 2, + "datasource_type": "table", + "params": "{\"viz_type\":\"line\",\"metrics\":[\"count\"]}" }, { "slice_name": "4 - Sample chart", @@ -32,7 +35,8 @@ "owners": [1], "viz_type": "line", "cache_timeout": 1000, - "datasource_id": 1, - "datasource_type": "table" + "datasource_id": 2, + "datasource_type": "table", + "params": "{\"viz_type\":\"line\",\"metrics\":[\"count\"]}" } ] diff --git a/superset-frontend/cypress-base/cypress/fixtures/dashboards.json b/superset-frontend/cypress-base/cypress/fixtures/dashboards.json index 083d7647b9..e4bd57971a 100644 --- a/superset-frontend/cypress-base/cypress/fixtures/dashboards.json +++ b/superset-frontend/cypress-base/cypress/fixtures/dashboards.json @@ -14,5 +14,33 @@ { "dashboard_title": "4 - Sample dashboard", "slug": "4-sample-dashboard" + }, + { + "dashboard_title": "5 - Sample dashboard", + "slug": "5-sample-dashboard" + }, + { + "dashboard_title": "6 - Sample dashboard", + "slug": "6-sample-dashboard" + }, + { + "dashboard_title": "7 - Sample dashboard", + "slug": "7-sample-dashboard" + }, + { + "dashboard_title": "8 - Sample dashboard", + "slug": "8-sample-dashboard" + }, + { + "dashboard_title": "9 - Sample dashboard", + "slug": "9-sample-dashboard" + }, + { + "dashboard_title": "10 - Sample dashboard", + "slug": "10-sample-dashboard" + }, + { + "dashboard_title": "11 - Sample dashboard", + "slug": "11-sample-dashboard" } ] diff --git a/superset-frontend/cypress-base/cypress/integration/chart_list/list.test.ts b/superset-frontend/cypress-base/cypress/integration/chart_list/list.test.ts index 6981ead73a..9891b09be7 100644 --- a/superset-frontend/cypress-base/cypress/integration/chart_list/list.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/chart_list/list.test.ts @@ -23,7 +23,11 @@ import { interceptBulkDelete, interceptUpdate, interceptDelete, + visitSampleChartFromList, + saveChartToDashboard, + interceptFiltering, } from '../explore/utils'; +import { interceptGet as interceptDashboardGet } from '../dashboard/utils'; function orderAlphabetical() { setFilter('Sort', 'Alphabetical'); @@ -43,14 +47,69 @@ function confirmDelete() { cy.getBySel('modal-confirm-button').click(); } +function visitChartList() { + interceptFiltering(); + cy.visit(CHART_LIST); + cy.wait('@filtering'); +} + describe('Charts list', () => { beforeEach(() => { cy.preserveLogin(); }); + describe('Cross-referenced dashboards', () => { + beforeEach(() => { + visitChartList(); + }); + + before(() => { + cy.createSampleDashboards([0, 1, 2, 3]); + cy.createSampleCharts([0]); + }); + + it('should show the cross-referenced dashboards in the table cell', () => { + interceptDashboardGet(); + cy.getBySel('table-row') + .first() + .find('[data-test="table-row-cell"]') + .find('[data-test="crosslinks"]') + .should('be.empty'); + cy.getBySel('table-row') + .eq(10) + .find('[data-test="table-row-cell"]') + .find('[data-test="crosslinks"]') + .contains('Supported Charts Dashboard') + .invoke('removeAttr', 'target') + .click(); + cy.wait('@get'); + }); + + it('should show the newly added dashboards in a tooltip', () => { + interceptDashboardGet(); + visitSampleChartFromList('1 - Sample chart'); + saveChartToDashboard('1 - Sample dashboard'); + saveChartToDashboard('2 - Sample dashboard'); + saveChartToDashboard('3 - Sample dashboard'); + saveChartToDashboard('4 - Sample dashboard'); + visitChartList(); + cy.getBySel('count-crosslinks').should('be.visible'); + cy.getBySel('crosslinks') + .first() + .trigger('mouseover') + .then(() => { + cy.get('.ant-tooltip') + .contains('4 - Sample dashboard') + .invoke('removeAttr', 'target') + .click(); + cy.wait('@get'); + }); + }); + }); + describe('list mode', () => { before(() => { - cy.visit(CHART_LIST); + visitChartList(); setGridMode('list'); }); @@ -94,7 +153,7 @@ describe('Charts list', () => { describe('card mode', () => { before(() => { - cy.visit(CHART_LIST); + visitChartList(); setGridMode('card'); }); @@ -126,8 +185,8 @@ describe('Charts list', () => { describe('common actions', () => { beforeEach(() => { - cy.createSampleCharts(); - cy.visit(CHART_LIST); + cy.createSampleCharts([0, 1, 2, 3]); + visitChartList(); }); it('should allow to favorite/unfavorite', () => { diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/actions.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/actions.test.js index de7c412934..8d520d9729 100644 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/actions.test.js +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/actions.test.js @@ -21,7 +21,7 @@ import { interceptFav, interceptUnfav } from './utils'; describe('Dashboard actions', () => { beforeEach(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0]); cy.visit(SAMPLE_DASHBOARD_1); }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/editmode.test.ts b/superset-frontend/cypress-base/cypress/integration/dashboard/editmode.test.ts index 0fffc58595..6ed1ec4ee0 100644 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/editmode.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/editmode.test.ts @@ -648,7 +648,7 @@ describe('Dashboard edit', () => { describe('Edit properties', () => { before(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0]); visitEdit(); }); @@ -700,7 +700,7 @@ describe('Dashboard edit', () => { describe('Edit mode', () => { before(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0]); visitEdit(); }); @@ -737,7 +737,7 @@ describe('Dashboard edit', () => { describe('Components', () => { before(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0]); }); beforeEach(() => { diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/nativeFilters.test.ts b/superset-frontend/cypress-base/cypress/integration/dashboard/nativeFilters.test.ts index 184ac86139..3f643cc32e 100644 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/nativeFilters.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/nativeFilters.test.ts @@ -196,7 +196,7 @@ describe('Native filters', () => { describe('Nativefilters tests initial state required', () => { beforeEach(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0]); }); it('Verify that default value is respected after revisit', () => { @@ -379,7 +379,7 @@ describe('Native filters', () => { describe('Nativefilters basic interactions', () => { before(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0]); visitDashboard(); }); @@ -437,7 +437,7 @@ describe('Native filters', () => { describe('Nativefilters initial state not required', () => { beforeEach(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0]); }); it("User can check 'Filter has default value'", () => { diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard_list/list.test.ts b/superset-frontend/cypress-base/cypress/integration/dashboard_list/list.test.ts index c25b11e7b3..aeee9ba499 100644 --- a/superset-frontend/cypress-base/cypress/integration/dashboard_list/list.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/dashboard_list/list.test.ts @@ -127,7 +127,7 @@ describe('Dashboards list', () => { describe('common actions', () => { beforeEach(() => { - cy.createSampleDashboards(); + cy.createSampleDashboards([0, 1, 2, 3]); cy.visit(DASHBOARD_LIST); }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js b/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js index ca37bf9690..0dfc9bd46b 100644 --- a/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js +++ b/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js @@ -16,7 +16,113 @@ * specific language governing permissions and limitations * under the License. */ +import { CHART_LIST } from 'cypress/utils/urls'; +import { interceptGet as interceptDashboardGet } from 'cypress/integration/dashboard/utils'; import { FORM_DATA_DEFAULTS, NUM_METRIC } from './visualizations/shared.helper'; +import { + interceptFiltering, + saveChartToDashboard, + visitSampleChartFromList, +} from './utils'; + +// SEARCH_THRESHOLD is 10. We need to add at least 11 dashboards to show search +const SAMPLE_DASHBOARDS_INDEXES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + +function openDashboardsAddedTo() { + cy.getBySel('actions-trigger').click(); + cy.get('.ant-dropdown-menu-submenu-title') + .contains('Dashboards added to') + .trigger('mouseover'); +} + +function closeDashboardsAddedTo() { + cy.get('.ant-dropdown-menu-submenu-title') + .contains('Dashboards added to') + .trigger('mouseout'); + cy.getBySel('actions-trigger').click(); +} + +function verifyDashboardsSubmenuItem(dashboardName) { + cy.get('.ant-dropdown-menu-submenu-popup').contains(dashboardName); + closeDashboardsAddedTo(); +} + +function verifyDashboardSearch() { + openDashboardsAddedTo(); + cy.get('.ant-dropdown-menu-submenu-popup').trigger('mouseover'); + cy.get('.ant-dropdown-menu-submenu-popup') + .find('input[placeholder="Search"]') + .type('1'); + cy.get('.ant-dropdown-menu-submenu-popup').contains('1 - Sample dashboard'); + cy.get('.ant-dropdown-menu-submenu-popup') + .find('input[placeholder="Search"]') + .type('Blahblah'); + cy.get('.ant-dropdown-menu-submenu-popup').contains('No results found'); + cy.get('.ant-dropdown-menu-submenu-popup') + .find('[aria-label="close-circle"]') + .click(); + closeDashboardsAddedTo(); +} + +function verifyDashboardLink() { + interceptDashboardGet(); + openDashboardsAddedTo(); + cy.get('.ant-dropdown-menu-submenu-popup').trigger('mouseover'); + cy.get('.ant-dropdown-menu-submenu-popup a') + .first() + .invoke('removeAttr', 'target') + .click(); + cy.wait('@get'); +} + +function verifyMetabar(text) { + cy.getBySel('metadata-bar').contains(text); +} + +function saveAndVerifyDashboard(number) { + saveChartToDashboard(`${number} - Sample dashboard`); + verifyMetabar(`Added to ${number} dashboard(s)`); + openDashboardsAddedTo(); + verifyDashboardsSubmenuItem(`${number} - Sample dashboard`); +} + +describe('Cross-referenced dashboards', () => { + beforeEach(() => { + interceptFiltering(); + + cy.preserveLogin(); + cy.visit(CHART_LIST); + cy.wait('@filtering'); + }); + + before(() => { + cy.createSampleDashboards(SAMPLE_DASHBOARDS_INDEXES); + cy.createSampleCharts([0]); + }); + + it('should show the cross-referenced dashboards', () => { + visitSampleChartFromList('1 - Sample chart'); + + cy.getBySel('metadata-bar').contains('Not added to any dashboard'); + openDashboardsAddedTo(); + verifyDashboardsSubmenuItem('None'); + + saveAndVerifyDashboard('1'); + saveAndVerifyDashboard('2'); + saveAndVerifyDashboard('3'); + saveAndVerifyDashboard('4'); + saveAndVerifyDashboard('5'); + saveAndVerifyDashboard('6'); + saveAndVerifyDashboard('7'); + saveAndVerifyDashboard('8'); + saveAndVerifyDashboard('9'); + saveAndVerifyDashboard('10'); + saveAndVerifyDashboard('11'); + + verifyDashboardSearch(); + verifyDashboardLink(); + }); +}); describe('No Results', () => { beforeEach(() => { diff --git a/superset-frontend/cypress-base/cypress/integration/explore/utils.ts b/superset-frontend/cypress-base/cypress/integration/explore/utils.ts index 99efedcd53..83e391acc0 100644 --- a/superset-frontend/cypress-base/cypress/integration/explore/utils.ts +++ b/superset-frontend/cypress-base/cypress/integration/explore/utils.ts @@ -49,3 +49,23 @@ export function setFilter(filter: string, option: string) { cy.wait('@filtering'); } + +export function saveChartToDashboard(dashboardName: string) { + cy.getBySel('query-save-button').click(); + cy.get( + '[data-test="save-chart-modal-select-dashboard-form"] [aria-label="Select a dashboard"]', + ) + .first() + .click(); + cy.get( + '.ant-select-selection-search-input[aria-label="Select a dashboard"]', + ).type(dashboardName); + cy.get(`.ant-select-item-option[title="${dashboardName}"]`).click(); + cy.getBySel('btn-modal-save').click(); +} + +export function visitSampleChartFromList(chartName: string) { + cy.getBySel('table-row').contains(chartName).click(); + cy.intercept('POST', '/superset/explore_json/**').as('getJson'); + cy.wait(500); +} diff --git a/superset-frontend/src/components/ListView/CrossLinks.tsx b/superset-frontend/src/components/ListView/CrossLinks.tsx index 3941bcf6ca..653e97b06e 100644 --- a/superset-frontend/src/components/ListView/CrossLinks.tsx +++ b/superset-frontend/src/components/ListView/CrossLinks.tsx @@ -112,7 +112,7 @@ export default function CrossLinks({ > {links} {hasHiddenElements && ( - + +{elementsTruncated} )} diff --git a/superset-frontend/src/components/MetadataBar/MetadataBar.tsx b/superset-frontend/src/components/MetadataBar/MetadataBar.tsx index 57733b7160..3756722523 100644 --- a/superset-frontend/src/components/MetadataBar/MetadataBar.tsx +++ b/superset-frontend/src/components/MetadataBar/MetadataBar.tsx @@ -203,7 +203,7 @@ const MetadataBar = ({ items }: MetadataBarProps) => { const { ref } = useResizeDetector({ onResize }); return ( - + {sortedItems.map((item, index) => (