This is an automated email from the ASF dual-hosted git repository.
ccwilliams pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 395359f [cypress] add integration tests for dashboard (#6002)
395359f is described below
commit 395359f5ad328e22923a9bc4fb580b1d8eb3b00c
Author: Grace Guo <[email protected]>
AuthorDate: Tue Oct 9 10:03:50 2018 -0700
[cypress] add integration tests for dashboard (#6002)
---
.../cypress/integration/dashboard/_controls.js | 69 ++++++++++++++++++++++
.../cypress/integration/dashboard/_edit_mode.js | 62 +++++++++++++++++++
.../cypress/integration/dashboard/_filter.js | 51 ++++++++++++++++
.../assets/cypress/integration/dashboard/_load.js | 34 +++++++++++
.../assets/cypress/integration/dashboard/all.js | 11 ++++
.../integration/dashboard/dashboard.helper.js | 4 ++
.../integration/dashboard/dashboard_tests.js | 28 ---------
7 files changed, 231 insertions(+), 28 deletions(-)
diff --git a/superset/assets/cypress/integration/dashboard/_controls.js
b/superset/assets/cypress/integration/dashboard/_controls.js
new file mode 100644
index 0000000..cfde066
--- /dev/null
+++ b/superset/assets/cypress/integration/dashboard/_controls.js
@@ -0,0 +1,69 @@
+import { WORLD_HEALTH_DASHBOARD, CHECK_DASHBOARD_FAVORITE_ENDPOINT } from
'./dashboard.helper';
+
+export default () => describe('top-level controls', () => {
+ let sliceIds = [];
+ let dashboard = {};
+ let isFavoriteDashboard = false;
+
+ beforeEach(() => {
+ cy.server();
+ cy.login();
+
+ cy.route(CHECK_DASHBOARD_FAVORITE_ENDPOINT).as('countFavStar');
+ cy.visit(WORLD_HEALTH_DASHBOARD);
+
+ cy.get('#app').then((data) => {
+ const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
+ dashboard = bootstrapData.dashboard_data;
+ sliceIds = dashboard.slices.map(slice => (slice.slice_id));
+ });
+
+ cy.wait('@countFavStar').then((xhr) => {
+ isFavoriteDashboard = xhr.response.body.count === 1;
+ });
+ });
+
+ it('should allow favor/unfavor', () => {
+ if (!isFavoriteDashboard) {
+ cy.get('.favstar').find('i').should('have.class', 'fa-star-o');
+ cy.get('.favstar').trigger('click');
+ cy.get('.favstar').find('i').should('have.class', 'fa-star')
+ .and('not.have.class', 'fa-star-o');
+ } else {
+ cy.get('.favstar').find('i').should('have.class', 'fa-star')
+ .and('not.have.class', 'fa-star-o');
+ cy.get('.favstar').trigger('click');
+ cy.get('.fave-unfave-icon').find('i').should('have.class', 'fa-star-o')
+ .and('not.have.class', 'fa-star');
+ }
+
+ // reset to original fav state
+ cy.get('.favstar').trigger('click');
+ });
+
+ it('should allow auto refresh', () => {
+ const sliceRequests = [];
+ const forceRefreshRequests = [];
+ sliceIds
+ .forEach((id) => {
+ const sliceRequest = `getJson_${id}`;
+ sliceRequests.push(`@${sliceRequest}`);
+ cy.route('POST',
`/superset/explore_json/?form_data={"slice_id":${id}}`).as(sliceRequest);
+
+ const forceRefresh = `getJson_${id}_force`;
+ forceRefreshRequests.push(`@${forceRefresh}`);
+ cy.route('POST',
`/superset/explore_json/?form_data={"slice_id":${id}}&force=true`).as(forceRefresh);
+ });
+
+ cy.wait(sliceRequests);
+ cy.get('#save-dash-split-button').trigger('click');
+ cy.contains('Force refresh dashboard').click();
+
+ cy.wait(forceRefreshRequests).then((xhrs) => {
+ // is_cached in response should be false
+ xhrs.forEach((xhr) => {
+ expect(xhr.response.body.is_cached).to.equal(false);
+ });
+ });
+ });
+});
diff --git a/superset/assets/cypress/integration/dashboard/_edit_mode.js
b/superset/assets/cypress/integration/dashboard/_edit_mode.js
new file mode 100644
index 0000000..842706a
--- /dev/null
+++ b/superset/assets/cypress/integration/dashboard/_edit_mode.js
@@ -0,0 +1,62 @@
+import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper';
+
+export default () => describe('edit mode', () => {
+ beforeEach(() => {
+ cy.server();
+ cy.login();
+
+ cy.visit(WORLD_HEALTH_DASHBOARD);
+ cy.get('#app').then((data) => {
+ const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
+ const dashboard = bootstrapData.dashboard_data;
+ const boxplotChartId = dashboard.slices.find(slice =>
(slice.form_data.viz_type === 'box_plot')).slice_id;
+ const boxplotRequest =
`/superset/explore_json/?form_data={"slice_id":${boxplotChartId}}`;
+ cy.route('POST', boxplotRequest).as('boxplotRequest');
+ });
+
+ cy.get('.dashboard-header').contains('Edit dashboard').click();
+ });
+
+ it('remove, and add chart flow', () => {
+ // wait box_plot data and find box plot
+ cy.wait('@boxplotRequest');
+ cy.get('.grid-container .box_plot').should('be.exist');
+
+ cy.get('.fa.fa-trash').last().then(($el) => {
+ cy.wrap($el).invoke('show').click();
+
+ // box plot should be gone
+ cy.get('.grid-container .box_plot').should('not.exist');
+ });
+
+ // open charts list
+ cy.get('.component-layer').contains('Your charts & filters').click();
+
+ // find box plot is available from list
+ cy.get('.slices-layer').find('.chart-card-container').contains('Box plot');
+
+ // drag-n-drop
+ const dataTransfer = { data: {} };
+ cy.get('.dragdroppable').contains('Box plot')
+ .trigger('mousedown', { which: 1 })
+ .trigger('dragstart', { dataTransfer })
+ .trigger('drag', {});
+ cy.get('.grid-content .dragdroppable').last()
+ .trigger('dragover', { dataTransfer })
+ .trigger('drop', { dataTransfer })
+ .trigger('dragend', { dataTransfer })
+ .trigger('mouseup', { which: 1 });
+
+ // add back to dashboard
+ cy.get('.grid-container .box_plot').should('be.exist');
+
+ // should show Save changes button
+ cy.get('.dashboard-header .button-container').contains('Save changes');
+
+ // undo 2 steps
+ cy.get('.dashboard-header .undo-action').click().click();
+
+ // no changes, can switch to view mode
+ cy.get('.dashboard-header .button-container').contains('Switch to view
mode').click();
+ });
+});
diff --git a/superset/assets/cypress/integration/dashboard/_filter.js
b/superset/assets/cypress/integration/dashboard/_filter.js
new file mode 100644
index 0000000..fe236db
--- /dev/null
+++ b/superset/assets/cypress/integration/dashboard/_filter.js
@@ -0,0 +1,51 @@
+import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper';
+
+export default () => describe('dashboard filter', () => {
+ let sliceIds = [];
+ let filterId;
+
+ beforeEach(() => {
+ cy.server();
+ cy.login();
+
+ cy.visit(WORLD_HEALTH_DASHBOARD);
+
+ cy.get('#app').then((data) => {
+ const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
+ const dashboard = bootstrapData.dashboard_data;
+ sliceIds = dashboard.slices.map(slice => (slice.slice_id));
+ filterId = dashboard.slices.find(slice => (slice.form_data.viz_type ===
'filter_box')).slice_id;
+ });
+ });
+
+ it('should apply filter', () => {
+ const aliases = [];
+
+ const filterRoute =
`/superset/explore_json/?form_data={"slice_id":${filterId}}`;
+ cy.route('POST', filterRoute).as('fetchFilter');
+ cy.wait('@fetchFilter');
+ sliceIds
+ .filter(id => (parseInt(id, 10) !== filterId))
+ .forEach((id) => {
+ const alias = `getJson_${id}`;
+ aliases.push(`@${alias}`);
+
+ cy.route('POST',
`/superset/explore_json/?form_data={"slice_id":${id}}`).as(alias);
+ });
+
+ // select filter_box and apply
+ cy.get('.Select-control')
+ .first().find('input')
+ .first()
+ .type('South Asia{enter}', { force: true });
+
+ cy.wait(aliases).then((requests) => {
+ requests.forEach((request) => {
+ const requestBody =
request.request.body.substring('form_data='.length);
+ const requestParams = JSON.parse(decodeURIComponent(requestBody));
+ expect(requestParams.extra_filters[0])
+ .deep.eq({ col: 'region', op: 'in', val: ['South+Asia'] });
+ });
+ });
+ });
+});
diff --git a/superset/assets/cypress/integration/dashboard/_load.js
b/superset/assets/cypress/integration/dashboard/_load.js
new file mode 100644
index 0000000..4da064b
--- /dev/null
+++ b/superset/assets/cypress/integration/dashboard/_load.js
@@ -0,0 +1,34 @@
+import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper';
+
+export default () => describe('load', () => {
+ const aliases = [];
+
+ beforeEach(() => {
+ cy.server();
+ cy.login();
+
+ cy.visit(WORLD_HEALTH_DASHBOARD);
+
+ cy.get('#app').then((data) => {
+ const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
+ const slices = bootstrapData.dashboard_data.slices;
+ // then define routes and create alias for each requests
+ slices.forEach((slice) => {
+ const alias = `getJson_${slice.slice_id}`;
+ cy.route('POST',
`/superset/explore_json/?form_data={"slice_id":${slice.slice_id}}`).as(alias);
+ aliases.push(`@${alias}`);
+ });
+ });
+ });
+
+ it('should load dashboard', () => {
+ // wait and verify one-by-one
+ cy.wait(aliases).then((requests) => {
+ requests.forEach((xhr) => {
+ expect(xhr.status).to.eq(200);
+ expect(xhr.response.body).to.have.property('error', null);
+ cy.get(`#slice-container-${xhr.response.body.form_data.slice_id}`);
+ });
+ });
+ });
+});
diff --git a/superset/assets/cypress/integration/dashboard/all.js
b/superset/assets/cypress/integration/dashboard/all.js
new file mode 100644
index 0000000..e448319
--- /dev/null
+++ b/superset/assets/cypress/integration/dashboard/all.js
@@ -0,0 +1,11 @@
+import DashboardControlsTest from './_controls';
+import DashboardEditModeTest from './_edit_mode';
+import DashboardFilterTest from './_filter';
+import DashboardLoadTest from './_load';
+
+describe('Dashboard', () => {
+ DashboardControlsTest();
+ DashboardEditModeTest();
+ DashboardFilterTest();
+ DashboardLoadTest();
+});
diff --git a/superset/assets/cypress/integration/dashboard/dashboard.helper.js
b/superset/assets/cypress/integration/dashboard/dashboard.helper.js
new file mode 100644
index 0000000..99cf861
--- /dev/null
+++ b/superset/assets/cypress/integration/dashboard/dashboard.helper.js
@@ -0,0 +1,4 @@
+export const WORLD_HEALTH_DASHBOARD = '/superset/dashboard/world_health';
+
+export const CHECK_DASHBOARD_FAVORITE_ENDPOINT =
'/superset/favstar/Dashboard/*/count';
+
diff --git a/superset/assets/cypress/integration/dashboard/dashboard_tests.js
b/superset/assets/cypress/integration/dashboard/dashboard_tests.js
deleted file mode 100644
index 75e84b7..0000000
--- a/superset/assets/cypress/integration/dashboard/dashboard_tests.js
+++ /dev/null
@@ -1,28 +0,0 @@
-describe('Load dashboard', () => {
- xit('Load birth names dashboard', () => {
- cy.server();
- cy.login();
- // go to the dashboard and get list of slices first
- cy.visit('/superset/dashboard/births');
- cy.get('#app').then((data) => {
- const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
- const slices = bootstrapData.dashboard_data.slices;
- // then define routes and create alias for each requests
- const aliases = slices.map((slice) => {
- const alias = `getJson_${slice.slice_id}`;
- cy.route('POST',
`/superset/explore_json/?form_data={"slice_id":${slice.slice_id}}`).as(alias);
- return `@${alias}`;
- });
- // reload the dashboard again with all routes watched.
- cy.visit('/superset/dashboard/births');
- // wait and verify one-by-one
- aliases.forEach((alias) => {
- cy.wait(alias).then((xhr) => {
- expect(xhr.status).to.eq(200);
- expect(xhr.response.body).to.have.property('error', null);
- cy.get(`#slice-container-${xhr.response.body.form_data.slice_id}`);
- });
- });
- });
- });
-});