This is an automated email from the ASF dual-hosted git repository.
graceguo 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 b7d5554 Cypress tests for controls and explore links (#6069)
b7d5554 is described below
commit b7d555420d21c4a13359ce857670860dbe712fe4
Author: michellethomas <[email protected]>
AuthorDate: Thu Oct 11 14:13:04 2018 -0700
Cypress tests for controls and explore links (#6069)
* Adding tests for controls
* Adding tests for explore links
---
.../cypress/integration/explore/control.test.js | 227 ++++++++++++++++++++-
.../cypress/integration/explore/link.test.js | 140 +++++++++++++
.../explore/visualizations/shared.helper.js | 7 +
superset/assets/cypress/support/commands.js | 4 +-
.../assets/src/components/URLShortLinkButton.jsx | 2 +-
.../AdhocFilterEditPopoverSimpleTabContent.jsx | 2 +-
.../src/explore/components/ControlHeader.jsx | 3 +
.../src/explore/components/EmbedCodeButton.jsx | 2 +-
.../assets/src/explore/components/SaveModal.jsx | 2 +
9 files changed, 374 insertions(+), 15 deletions(-)
diff --git a/superset/assets/cypress/integration/explore/control.test.js
b/superset/assets/cypress/integration/explore/control.test.js
index a742d6d..2efa7b9 100644
--- a/superset/assets/cypress/integration/explore/control.test.js
+++ b/superset/assets/cypress/integration/explore/control.test.js
@@ -17,18 +17,20 @@ describe('Groupby', () => {
cy.get('.VirtualizedSelectFocusedOption').click();
});
cy.get('button.query').click();
- cy.verifySliceSuccess({ waitAlias: '@getJson' });
+ cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' });
});
});
-describe('SimpleAdhocMetric', () => {
- it('Clear metric and set simple adhoc metric', () => {
- cy.server();
+describe('AdhocMetrics', () => {
+ beforeEach(() => {
cy.login();
+ cy.server();
+ cy.route('POST', '/superset/explore_json/**').as('getJson');
+ });
+ it('Clear metric and set simple adhoc metric', () => {
const metricName = 'Girl Births';
- cy.route('POST', '/superset/explore_json/**').as('getJson');
cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@getJson' });
@@ -52,11 +54,216 @@ describe('SimpleAdhocMetric', () => {
});
cy.get('button.query').click();
- cy.wait(['@getJson']).then((data) => {
- expect(data.status).to.eq(200);
- expect(data.response.body).to.have.property('error', null);
- expect(data.response.body.data[0].key).to.equal(metricName);
- cy.get('.slice_container');
+ cy.verifySliceSuccess({
+ waitAlias: '@getJson',
+ querySubstring: metricName,
+ chartSelector: 'svg',
+ });
+ });
+
+ it('Clear metric and set custom sql adhoc metric', () => {
+ const metric = 'SUM(num)/COUNT(DISTINCT name)';
+
+ cy.visitChartByName('Num Births Trend');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=metrics]').within(() => {
+ cy.get('.select-clear').click();
+ cy.get('.Select-control').click({ force: true });
+ cy.get('input').type('num', { force: true });
+ cy.get('.VirtualizedSelectFocusedOption')
+ .trigger('mousedown')
+ .click();
+ });
+
+ cy.get('#metrics-edit-popover').within(() => {
+ cy.get('#adhoc-metric-edit-tabs-tab-SQL').click();
+ cy.get('.ace_content').click();
+ cy.get('.ace_text-input')
+ .type(`{selectall}{backspace}${metric}`, { force: true });
+ cy.get('button').contains('Save').click();
+ });
+
+ cy.get('button.query').click();
+ cy.verifySliceSuccess({
+ waitAlias: '@getJson',
+ querySubstring: metric,
+ chartSelector: 'svg',
+ });
+ });
+
+ it('Switch between simple and custom sql tabs', () => {
+ cy.visitChartByName('Num Births Trend');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=metrics]').within(() => {
+ cy.get('.select-clear').click();
+ cy.get('.Select-control').click({ force: true });
+ cy.get('input').type('sum_girls', { force: true });
+ cy.get('.VirtualizedSelectFocusedOption')
+ .trigger('mousedown')
+ .click();
+ });
+
+ cy.get('#metrics-edit-popover').within(() => {
+ cy.get('#adhoc-metric-edit-tabs-tab-SQL').click();
+ cy.get('.ace_identifier').contains('sum_girls');
+ cy.get('.ace_content').click();
+ cy.get('.ace_text-input')
+ .type('{selectall}{backspace}SUM(num)', { force: true });
+ cy.get('#adhoc-metric-edit-tabs-tab-SIMPLE').click();
+ cy.get('.select-value-label').contains('num');
+ cy.get('button').contains('Save').click();
+ });
+
+ cy.get('button.query').click();
+ cy.verifySliceSuccess({
+ waitAlias: '@getJson',
+ chartSelector: 'svg',
});
});
});
+
+describe('AdhocFilters', () => {
+ beforeEach(() => {
+ cy.login();
+ cy.server();
+ cy.route('POST', '/superset/explore_json/**').as('getJson');
+ });
+
+ it('Set simple adhoc filter', () => {
+ cy.visitChartByName('Num Births Trend');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=adhoc_filters]').within(() => {
+ cy.get('.Select-control').click({ force: true });
+ cy.get('input').type('name', { force: true });
+ cy.get('.VirtualizedSelectFocusedOption')
+ .trigger('mousedown')
+ .click();
+ });
+
+ cy.get('#filter-edit-popover').within(() => {
+ cy.get('[data-test=adhoc-filter-simple-value]').within(() => {
+ cy.get('div.select-input').click({ force: true });
+ cy.get('input.select-input').type('Amy', { force: true });
+ cy.get('.VirtualizedSelectFocusedOption')
+ .trigger('mousedown')
+ .click();
+ });
+ cy.get('button')
+ .contains('Save')
+ .click();
+ });
+
+ cy.get('button.query').click();
+ cy.verifySliceSuccess({
+ waitAlias: '@getJson',
+ chartSelector: 'svg',
+ });
+ });
+
+ it('Set custom adhoc filter', () => {
+ cy.visitChartByName('Num Births Trend');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=adhoc_filters]').within(() => {
+ cy.get('.Select-control').click({ force: true });
+ cy.get('input').type('name', { force: true });
+ cy.get('.VirtualizedSelectFocusedOption')
+ .trigger('mousedown')
+ .click();
+ });
+
+ 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'", { force: true });
+ cy.get('button')
+ .contains('Save')
+ .click();
+ });
+
+ cy.get('button.query').click();
+ cy.verifySliceSuccess({
+ waitAlias: '@getJson',
+ chartSelector: 'svg',
+ });
+ });
+});
+
+
+describe('Advanced analytics', () => {
+ beforeEach(() => {
+ cy.login();
+ cy.server();
+ cy.route('POST', '/superset/explore_json/**').as('getJson');
+ });
+
+ it('Create custom time compare', () => {
+ cy.visitChartByName('Num Births Trend');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('span')
+ .contains('Advanced Analytics')
+ .siblings()
+ .first()
+ .click();
+
+ cy.get('[data-test=time_compare]').within(() => {
+ cy.get('.Select-control').click({ force: true });
+ cy.get('input').type('364 days', { force: true });
+ cy.get('.VirtualizedSelectOption')
+ .trigger('mousedown')
+ .click();
+ });
+
+ cy.get('button.query').click();
+ cy.wait('@getJson');
+ cy.reload();
+ cy.verifySliceSuccess({
+ waitAlias: '@getJson',
+ chartSelector: 'svg',
+ });
+
+ cy.get('[data-test=time_compare]').within(() => {
+ cy.get('.select-value-label').contains('364 days');
+ });
+ });
+});
+
+describe('Annotations', () => {
+ beforeEach(() => {
+ cy.login();
+ cy.server();
+ cy.route('POST', '/superset/explore_json/**').as('getJson');
+ });
+
+ it('Create formula annotation y-axis goal line', () => {
+ cy.visitChartByName('Num Births Trend');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=annotation_layers]').within(() => {
+ cy.get('button').click();
+ });
+
+ cy.get('.popover-content').within(() => {
+
cy.get('[data-test=annotation-layer-name-header]').siblings().first().within(()
=> {
+ cy.get('input').type('Goal line');
+ });
+
cy.get('[data-test=annotation-layer-value-header]').siblings().first().within(()
=> {
+ cy.get('input').type('y=1400000');
+ });
+ cy.get('button').contains('OK').click();
+ });
+
+ cy.get('button.query').click();
+ cy.verifySliceSuccess({
+ waitAlias: '@getJson',
+ chartSelector: 'svg',
+ });
+
+ cy.get('.nv-legend-text').should('have.length', 2);
+ });
+});
diff --git a/superset/assets/cypress/integration/explore/link.test.js
b/superset/assets/cypress/integration/explore/link.test.js
new file mode 100644
index 0000000..dc84e62
--- /dev/null
+++ b/superset/assets/cypress/integration/explore/link.test.js
@@ -0,0 +1,140 @@
+// ***********************************************
+// Tests for links in the explore UI
+// ***********************************************
+
+import { HEALTH_POP_FORM_DATA_DEFAULTS } from './visualizations/shared.helper';
+
+describe('Test explore links', () => {
+ beforeEach(() => {
+ cy.login();
+ cy.server();
+ cy.route('POST', '/superset/explore_json/**').as('getJson');
+ });
+
+ it('Open and close view query modal', () => {
+ cy.visitChartByName('Growth Rate');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('button#query').click();
+ cy.get('span').contains('View query').parent().click();
+ cy.wait('@getJson').then(() => {
+ cy.get('code');
+ });
+ cy.get('.modal-header').within(() => {
+ cy.get('button.close').first().click({ force: true });
+ });
+ });
+
+ it('Visit short link', () => {
+ cy.visitChartByName('Growth Rate');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=short-link-button]').click();
+ cy.get('#shorturl-popover').within(() => {
+ cy.get('i[title="Copy to clipboard"]')
+ .siblings()
+ .first()
+ .invoke('text')
+ .then((text) => {
+ cy.visit(text);
+ });
+ });
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+ });
+
+ it('Test iframe link', () => {
+ cy.visitChartByName('Growth Rate');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=embed-code-button]').click();
+ cy.get('#embed-code-popover').within(() => {
+ cy.get('textarea[name=embedCode]').contains('iframe');
+ });
+ });
+
+ it('Test chart save as', () => {
+ const formData = {
+ ...HEALTH_POP_FORM_DATA_DEFAULTS,
+ viz_type: 'table',
+ metrics: ['sum__SP_POP_TOTL'],
+ groupby: ['country_name'],
+ };
+ const newChartName = 'Test chart';
+
+ cy.visitChartByParams(JSON.stringify(formData));
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+ cy.url().then((url) => {
+ cy.get('button[data-target="#save_modal"]').click();
+ cy.get('.modal-content').within(() => {
+ cy.get('input[name=new_slice_name]').type(newChartName);
+ cy.get('button#btn_modal_save').click();
+ });
+ cy.url().should('eq', url);
+
+ cy.visitChartByName(newChartName);
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+ });
+ });
+
+ it('Test chart save', () => {
+ const chartName = 'Test chart';
+ cy.visitChartByName(chartName);
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ cy.get('[data-test=groupby]').within(() => {
+ cy.get('span.select-clear-zone').click();
+ });
+ cy.get('button[data-target="#save_modal"]').click();
+ cy.get('.modal-content').within(() => {
+ cy.get('button#btn_modal_save').click();
+ });
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
cy.request(`/chart/api/read?_flt_3_slice_name=${chartName}`).then((response) =>
{
+ cy.request('DELETE', `/chart/api/delete/${response.body.pks[0]}`);
+ });
+ });
+
+ it('Test chart save as and add to new dashboard', () => {
+ cy.visitChartByName('Growth Rate');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
+ const dashboardTitle = 'Test dashboard';
+ cy.get('button[data-target="#save_modal"]').click();
+ cy.get('.modal-content').within(() => {
+ cy.get('input[name=new_slice_name]').type('New Growth Rate');
+ cy.get('input[data-test=add-to-new-dashboard]').check();
+ cy.get('input[placeholder="[dashboard name]"]').type(dashboardTitle);
+ cy.get('button#btn_modal_save').click();
+ });
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
cy.request(`/dashboard/api/read?_flt_3_dashboard_title=${dashboardTitle}`).then((response)
=> {
+ expect(response.body.pks[0]).not.equals(null);
+ });
+ });
+
+ it('Test chart save as and add to existing dashboard', () => {
+ cy.visitChartByName('Most Populated Countries');
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+ const chartName = 'New Most Populated Countries';
+ const dashboardTitle = 'Test dashboard';
+
+ cy.get('button[data-target="#save_modal"]').click();
+ cy.get('.modal-content').within(() => {
+ cy.get('input[name=new_slice_name]').type(chartName);
+ cy.get('input[data-test=add-to-existing-dashboard]').check();
+ cy.get('.select.save-modal-selector').click().within(() => {
+ cy.get('input').type(dashboardTitle, { force: true });
+ cy.get('.select-option.is-focused')
+ .trigger('mousedown');
+ });
+ cy.get('button#btn_modal_save').click();
+ });
+ cy.verifySliceSuccess({ waitAlias: '@getJson' });
+
cy.request(`/chart/api/read?_flt_3_slice_name=${chartName}`).then((response) =>
{
+ cy.request('DELETE', `/chart/api/delete/${response.body.pks[0]}`);
+ });
+
cy.request(`/dashboard/api/read?_flt_3_dashboard_title=${dashboardTitle}`).then((response)
=> {
+ cy.request('DELETE', `/dashboard/api/delete/${response.body.pks[0]}`);
+ });
+ });
+});
diff --git
a/superset/assets/cypress/integration/explore/visualizations/shared.helper.js
b/superset/assets/cypress/integration/explore/visualizations/shared.helper.js
index 796173a..e98c7ff 100644
---
a/superset/assets/cypress/integration/explore/visualizations/shared.helper.js
+++
b/superset/assets/cypress/integration/explore/visualizations/shared.helper.js
@@ -15,6 +15,13 @@ export const FORM_DATA_DEFAULTS = {
contribution: false,
};
+export const HEALTH_POP_FORM_DATA_DEFAULTS = {
+ datasource: '2__table',
+ granularity_sqla: 'ds',
+ time_grain_sqla: 'P1D',
+ time_range: '1960-01-01+:+2014-01-02',
+};
+
export const NUM_METRIC = {
expressionType: 'SIMPLE',
column: {
diff --git a/superset/assets/cypress/support/commands.js
b/superset/assets/cypress/support/commands.js
index a6c6dae..a8d432e 100644
--- a/superset/assets/cypress/support/commands.js
+++ b/superset/assets/cypress/support/commands.js
@@ -29,7 +29,7 @@ const BASE_EXPLORE_URL = '/superset/explore/?form_data=';
Cypress.Commands.add('login', () => {
cy.request({
method: 'POST',
- url: 'http://localhost:8081/login/',
+ url: '/login/',
body: { username: 'admin', password: 'general' },
}).then((response) => {
expect(response.status).to.eq(200);
@@ -37,7 +37,7 @@ Cypress.Commands.add('login', () => {
});
Cypress.Commands.add('visitChartByName', (name) => {
-
cy.request(`http://localhost:8081/chart/api/read?_flt_3_slice_name=${name}`).then((response)
=> {
+ cy.request(`/chart/api/read?_flt_3_slice_name=${name}`).then((response) => {
cy.visit(`${BASE_EXPLORE_URL}{"slice_id": ${response.body.pks[0]}}`);
});
});
diff --git a/superset/assets/src/components/URLShortLinkButton.jsx
b/superset/assets/src/components/URLShortLinkButton.jsx
index 19c77ab..86c1b59 100644
--- a/superset/assets/src/components/URLShortLinkButton.jsx
+++ b/superset/assets/src/components/URLShortLinkButton.jsx
@@ -58,7 +58,7 @@ class URLShortLinkButton extends React.Component {
onEnter={this.getCopyUrl}
overlay={this.renderPopover()}
>
- <span className="btn btn-default btn-sm">
+ <span className="btn btn-default btn-sm" data-test="short-link-button">
<i className="fa fa-link" />
</span>
</OverlayTrigger>
diff --git
a/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx
b/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx
index 6c670b6..4921647 100644
---
a/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx
+++
b/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx
@@ -257,7 +257,7 @@ export default class AdhocFilterEditPopoverSimpleTabContent
extends React.Compon
<FormGroup>
<OnPasteSelect {...this.selectProps} {...operatorSelectProps} />
</FormGroup>
- <FormGroup>
+ <FormGroup data-test="adhoc-filter-simple-value">
{
(
MULTI_OPERATORS.indexOf(adhocFilter.operator) >= 0 ||
diff --git a/superset/assets/src/explore/components/ControlHeader.jsx
b/superset/assets/src/explore/components/ControlHeader.jsx
index 3dd884c..9dcdc61 100644
--- a/superset/assets/src/explore/components/ControlHeader.jsx
+++ b/superset/assets/src/explore/components/ControlHeader.jsx
@@ -5,6 +5,7 @@ import InfoTooltipWithTrigger from
'../../components/InfoTooltipWithTrigger';
import { t } from '../../locales';
const propTypes = {
+ name: PropTypes.string,
label: PropTypes.string,
description: PropTypes.string,
validationErrors: PropTypes.array,
@@ -22,6 +23,7 @@ const defaultProps = {
validationErrors: [],
renderTrigger: false,
hovered: false,
+ name: undefined,
};
export default class ControlHeader extends React.Component {
@@ -63,6 +65,7 @@ export default class ControlHeader extends React.Component {
return (
<div
className="ControlHeader"
+ data-test={`${this.props.name}-header`}
>
<div className="pull-left">
<ControlLabel>
diff --git a/superset/assets/src/explore/components/EmbedCodeButton.jsx
b/superset/assets/src/explore/components/EmbedCodeButton.jsx
index a09a533..e6cccac 100644
--- a/superset/assets/src/explore/components/EmbedCodeButton.jsx
+++ b/superset/assets/src/explore/components/EmbedCodeButton.jsx
@@ -113,7 +113,7 @@ export default class EmbedCodeButton extends
React.Component {
placement="left"
overlay={this.renderPopover()}
>
- <span className="btn btn-default btn-sm">
+ <span className="btn btn-default btn-sm" data-test="embed-code-button">
<i className="fa fa-code" />
</span>
</OverlayTrigger>
diff --git a/superset/assets/src/explore/components/SaveModal.jsx
b/superset/assets/src/explore/components/SaveModal.jsx
index 7748cac..522ce04 100644
--- a/superset/assets/src/explore/components/SaveModal.jsx
+++ b/superset/assets/src/explore/components/SaveModal.jsx
@@ -188,6 +188,7 @@ class SaveModal extends React.Component {
disabled={canNotSaveToDash}
checked={this.state.addToDash === 'existing'}
onChange={this.changeDash.bind(this, 'existing')}
+ data-test="add-to-existing-dashboard"
>
{t('Add chart to existing dashboard')}
</Radio>
@@ -206,6 +207,7 @@ class SaveModal extends React.Component {
checked={this.state.addToDash === 'new'}
onChange={this.changeDash.bind(this, 'new')}
disabled={canNotSaveToDash}
+ data-test="add-to-new-dashboard"
>
{t('Add to new dashboard')}
</Radio>