Skip to content

Commit

Permalink
feat: move ace-editor and mathjs to async modules (apache#10837)
Browse files Browse the repository at this point in the history
Follow up on apache#10831, move brace and mathjs to async modules so that the initial page load for dashboards most pages can be faster.
  • Loading branch information
ktmud authored and auxten committed Nov 20, 2020
1 parent ff9a3db commit e73195d
Show file tree
Hide file tree
Showing 28 changed files with 765 additions and 269 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const WORLD_HEALTH_DASHBOARD = '/superset/dashboard/world_health/';
export const TABBED_DASHBOARD = '/superset/dashboard/tabbed_dash/';

export const CHECK_DASHBOARD_FAVORITE_ENDPOINT =
'/superset/favstar/Dashboard/*/count';

/**
* Drag an element and drop it to another element.
* Usage:
* drag(source).to(target);
*/
export function drag(selector: string, content: string | number | RegExp) {
const dataTransfer = { data: {} };
return {
to(target: string | Cypress.Chainable) {
cy.get('.dragdroppable')
.contains(selector, content)
.trigger('mousedown', { which: 1 })
.trigger('dragstart', { dataTransfer })
.trigger('drag', {});

(typeof target === 'string' ? cy.get(target) : target)
.trigger('dragover', { dataTransfer })
.trigger('drop', { dataTransfer })
.trigger('dragend', { dataTransfer })
.trigger('mouseup', { which: 1 });
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper';
import { WORLD_HEALTH_DASHBOARD, drag } from './dashboard.helper';

describe('Dashboard edit mode', () => {
beforeEach(() => {
Expand Down Expand Up @@ -45,19 +45,9 @@ describe('Dashboard edit mode', () => {
.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 div.grid-row.background--transparent')
.last()
.trigger('dragover', { dataTransfer })
.trigger('drop', { dataTransfer })
.trigger('dragend', { dataTransfer })
.trigger('mouseup', { which: 1 });
drag('.chart-card', 'Box plot').to(
'.grid-row.background--transparent:last',
);

// add back to dashboard
cy.get('.grid-container .box_plot').should('be.exist');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { TABBED_DASHBOARD, drag } from './dashboard.helper';

describe('Dashboard edit markdown', () => {
beforeEach(() => {
cy.server();
cy.login();
cy.visit(TABBED_DASHBOARD);
});

it('should load AceEditor on demand', () => {
let numScripts = 0;
cy.get('script').then(nodes => {
numScripts = nodes.length;
});
cy.get('.dashboard-header [data-test=pencil]').click();
cy.get('script').then(nodes => {
// load 5 new script chunks for css editor
expect(nodes.length).to.greaterThan(numScripts);
numScripts = nodes.length;
});

// add new markdown component
drag('.new-component', 'Markdown').to(
'.grid-row.background--transparent:first',
);
cy.get('script').then(nodes => {
// load more scripts for markdown editor
expect(nodes.length).to.greaterThan(numScripts);
numScripts = nodes.length;
});

cy.contains('h3', '✨Markdown').click();
cy.get('.ace_content').contains(
'Click here to edit [markdown](https://bit.ly/1dQOfRK)',
);

// entering edit mode does not add new scripts
// (though scripts may still be removed by others)
cy.get('script').then(nodes => {
expect(nodes.length).to.most(numScripts);
});

cy.get('.grid-row.background--transparent:first').click('right');
cy.get('.ace_content').should('not.exist');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,38 @@ describe('AdhocFilters', () => {
cy.route('GET', '/superset/filter/table/*/name').as('filterValues');
});

it('Set simple adhoc filter', () => {
cy.visitChartByName('Num Births Trend');
it('Should not load mathjs when not needed', () => {
cy.visitChartByName('Boys'); // a table chart
cy.verifySliceSuccess({ waitAlias: '@postJson' });
cy.get('script[src*="mathjs"]').should('have.length', 0);
});

let numScripts = 0;

it('Should load AceEditor scripts when needed', () => {
cy.get('script').then(nodes => {
numScripts = nodes.length;
});

cy.get('[data-test=adhoc_filters]').within(() => {
cy.get('.Select__control').click();
cy.get('.Select__control').scrollIntoView().click();
cy.get('input[type=text]').focus().type('name{enter}');
});

cy.get('script').then(nodes => {
// should load new script chunks for SQL editor
expect(nodes.length).to.greaterThan(numScripts);
});
});

it('Set simple adhoc filter', () => {
cy.get('#filter-edit-popover').within(() => {
cy.get('[data-test=adhoc-filter-simple-value]').within(() => {
cy.get('.Select__control').click();
cy.get('input[type=text]').focus().type('Any{enter}');
});
cy.get('button').contains('Save').click();
});

cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
waitAlias: '@postJson',
Expand All @@ -52,19 +68,21 @@ describe('AdhocFilters', () => {
cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@postJson' });

cy.get('[data-test=adhoc_filters]').within(() => {
cy.get('.Select__control').click();
cy.get('input[type=text]').focus().type('name{enter}');
});
cy.get('[data-test=adhoc_filters] .Select__control')
.scrollIntoView()
.click();
cy.get('[data-test=adhoc_filters] input[type=text]')
.focus()
.type('name{enter}');

cy.wait('@filterValues');

cy.get('#filter-edit-popover').within(() => {
cy.get('#adhoc-filter-edit-tabs-tab-SQL').click();
cy.get('.ace_content').click();
cy.get('.ace_text-input').type("'Amy' OR name = 'Bob'");
cy.get('button').contains('Save').click();
});
cy.get('#filter-edit-popover #adhoc-filter-edit-tabs-tab-SQL').click();
cy.get('#filter-edit-popover .ace_content').click();
cy.get('#filter-edit-popover .ace_text-input').type(
"'Amy' OR name = 'Bob'",
);
cy.get('#filter-edit-popover button').contains('Save').click();

cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,25 @@ describe('Datasource control', () => {
});

it('should allow edit datasource', () => {
let numScripts = 0;

cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@postJson' });
cy.get('#datasource_menu').click();

cy.get('script').then(nodes => {
numScripts = nodes.length;
});

cy.get('a').contains('Edit Datasource').click();

// should load additional scripts for the modal
cy.get('script').then(nodes => {
expect(nodes.length).to.greaterThan(numScripts);
});

// create new metric
cy.get('button').contains('Add Item').click();
cy.get('table button').contains('Add Item', { timeout: 10000 }).click();
cy.get('input[value="<new metric>"]').click();
cy.get('input[value="<new metric>"]')
.focus()
Expand Down Expand Up @@ -65,19 +78,33 @@ describe('Datasource control', () => {
});
});

describe('Groupby control', () => {
it('Set groupby', () => {
cy.server();
describe('VizType control', () => {
beforeEach(() => {
cy.login();
cy.server();
cy.route('GET', '/superset/explore_json/**').as('getJson');
cy.route('POST', '/superset/explore_json/**').as('postJson');
cy.visitChartByName('Num Births Trend');
});

it('Can change vizType', () => {
cy.visitChartByName('Daily Totals');
cy.verifySliceSuccess({ waitAlias: '@postJson' });

cy.get('[data-test=groupby]').within(() => {
cy.get('.Select__control').click();
cy.get('input[type=text]').type('state{enter}');
let numScripts = 0;
cy.get('script').then(nodes => {
numScripts = nodes.length;
});

cy.get('.Control .label').contains('Table').click();

cy.get('[role="button"]').contains('Line Chart').click();

// should load mathjs for line chart
cy.get('script[src*="mathjs"]').should('have.length', 1);
cy.get('script').then(nodes => {
expect(nodes.length).to.greaterThan(numScripts);
});

cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({ waitAlias: '@postJson', chartSelector: 'svg' });
});
Expand Down Expand Up @@ -118,3 +145,21 @@ describe('Time range filter', () => {
cy.get('#filter-popover').should('not.exist');
});
});

describe('Groupby control', () => {
it('Set groupby', () => {
cy.server();
cy.login();
cy.route('GET', '/superset/explore_json/**').as('getJson');
cy.route('POST', '/superset/explore_json/**').as('postJson');
cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@postJson' });

cy.get('[data-test=groupby]').within(() => {
cy.get('.Select__control').click();
cy.get('input[type=text]').type('state{enter}');
});
cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({ waitAlias: '@postJson', chartSelector: 'svg' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ describe('Visualization > Line', () => {
cy.get('.alert-warning').contains(`"Metrics" cannot be empty`);
});

it('should preload mathjs', () => {
cy.get('script[src*="mathjs"]').should('have.length', 1);
cy.contains('Add Annotation Layer').scrollIntoView().click();
// should not load additional mathjs
cy.get('script[src*="mathjs"]').should('have.length', 1);
cy.contains('Layer Configuration');
});

it('should not show validator error when metric added', () => {
const formData = { ...LINE_CHART_DEFAULTS, metrics: [] };
cy.visitChartByParams(JSON.stringify(formData));
Expand Down Expand Up @@ -68,6 +76,7 @@ describe('Visualization > Line', () => {
const formData = { ...LINE_CHART_DEFAULTS, metrics: [NUM_METRIC] };
cy.visitChartByParams(JSON.stringify(formData));
cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' });
cy.get('script[src*="mathjs"]').should('have.length', 1);
});

it('should work with groupby', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import { Provider } from 'react-redux';
import React from 'react';
import { mount } from 'enzyme';
import sinon from 'sinon';
import AceEditor from 'react-ace';
import ReactMarkdown from 'react-markdown';

import { MarkdownEditor } from 'src/components/AsyncAceEditor';
import Markdown from 'src/dashboard/components/gridComponents/Markdown';
import MarkdownModeDropdown from 'src/dashboard/components/menu/MarkdownModeDropdown';
import DeleteComponentButton from 'src/dashboard/components/DeleteComponentButton';
Expand Down Expand Up @@ -105,23 +105,23 @@ describe('Markdown', () => {

it('should render an Markdown when NOT focused', () => {
const wrapper = setup();
expect(wrapper.find(AceEditor)).not.toExist();
expect(wrapper.find(MarkdownEditor)).not.toExist();
expect(wrapper.find(ReactMarkdown)).toExist();
});

it('should render an AceEditor when focused and editMode=true and editorMode=edit', () => {
const wrapper = setup({ editMode: true });
expect(wrapper.find(AceEditor)).not.toExist();
expect(wrapper.find(MarkdownEditor)).not.toExist();
expect(wrapper.find(ReactMarkdown)).toExist();
wrapper.find(WithPopoverMenu).simulate('click'); // focus + edit
expect(wrapper.find(AceEditor)).toExist();
expect(wrapper.find(MarkdownEditor)).toExist();
expect(wrapper.find(ReactMarkdown)).not.toExist();
});

it('should render a ReactMarkdown when focused and editMode=true and editorMode=preview', () => {
const wrapper = setup({ editMode: true });
wrapper.find(WithPopoverMenu).simulate('click'); // focus + edit
expect(wrapper.find(AceEditor)).toExist();
expect(wrapper.find(MarkdownEditor)).toExist();
expect(wrapper.find(ReactMarkdown)).not.toExist();

// we can't call setState on Markdown bc it's not the root component, so call
Expand All @@ -131,7 +131,7 @@ describe('Markdown', () => {
wrapper.update();

expect(wrapper.find(ReactMarkdown)).toExist();
expect(wrapper.find(AceEditor)).not.toExist();
expect(wrapper.find(MarkdownEditor)).not.toExist();
});

it('should call updateComponents when editMode changes from edit => preview, and there are markdownSource changes', () => {
Expand All @@ -148,7 +148,7 @@ describe('Markdown', () => {
dropdown.prop('onChange')('edit');
// because we can't call setState on Markdown, change it through the editor
// then go back to preview mode to invoke updateComponents
const editor = wrapper.find(AceEditor);
const editor = wrapper.find(MarkdownEditor);
editor.prop('onChange')('new markdown!');
dropdown.prop('onChange')('preview');
expect(updateComponents.callCount).toBe(1);
Expand Down
Loading

0 comments on commit e73195d

Please sign in to comment.