mirror of https://github.com/apache/superset.git
[cypress] add integration tests for dashboard (#6002)
This commit is contained in:
parent
361f588b71
commit
395359f5ad
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
|
@ -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'] });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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();
|
||||||
|
});
|
|
@ -0,0 +1,4 @@
|
||||||
|
export const WORLD_HEALTH_DASHBOARD = '/superset/dashboard/world_health';
|
||||||
|
|
||||||
|
export const CHECK_DASHBOARD_FAVORITE_ENDPOINT = '/superset/favstar/Dashboard/*/count';
|
||||||
|
|
|
@ -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}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue