Skip to content

Commit

Permalink
Merge branch 'master' into fix-clean-form-data
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenLYZ committed Apr 5, 2022
2 parents 0104783 + a59718b commit 8c0ad91
Show file tree
Hide file tree
Showing 121 changed files with 2,287 additions and 1,371 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/superset-python-unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
- name: Python unit tests
if: steps.check.outcome == 'failure'
run: |
pytest --durations=0 ./tests/common ./tests/unit_tests --cache-clear
pytest --durations-min=0.5 --cov-report= --cov=superset ./tests/common ./tests/unit_tests --cache-clear
- name: Upload code coverage
if: steps.check.outcome == 'failure'
run: |
Expand Down
2 changes: 1 addition & 1 deletion RELEASING/Dockerfile.from_local_tarball
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ RUN apt-get install -y build-essential libssl-dev \

# Install nodejs for custom build
# https://nodejs.org/en/download/package-manager/
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - \
&& apt-get install -y nodejs

RUN mkdir -p /home/superset
Expand Down
2 changes: 1 addition & 1 deletion RELEASING/Dockerfile.from_svn_tarball
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ RUN apt-get install -y build-essential libssl-dev \

# Install nodejs for custom build
# https://nodejs.org/en/download/package-manager/
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - \
&& apt-get install -y nodejs

RUN mkdir -p /home/superset
Expand Down
1 change: 0 additions & 1 deletion UPDATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ assists people when migrating to a new version.
- [19231](https://github.com/apache/superset/pull/19231): The `ENABLE_REACT_CRUD_VIEWS` feature flag has been removed (permanently enabled). Any deployments which had set this flag to false will need to verify that the React views support their use case.
- [17556](https://github.com/apache/superset/pull/17556): Bumps mysqlclient from v1 to v2
- [19113](https://github.com/apache/superset/pull/19113): The `ENABLE_JAVASCRIPT_CONTROLS` setting has moved from app config to a feature flag. Any deployments who overrode this setting will now need to override the feature flag from here onward.
- [18976](https://github.com/apache/superset/pull/18976): When running the app in debug mode, the app will default to use `SimpleCache` for `FILTER_STATE_CACHE_CONFIG` and `EXPLORE_FORM_DATA_CACHE_CONFIG`. When running in non-debug mode, a cache backend will need to be defined, otherwise the application will fail to start. For installations using Redis or other caching backends, it is recommended to use the same backend for both cache configs.
- [17881](https://github.com/apache/superset/pull/17881): Previously simple adhoc filter values on string columns were stripped of enclosing single and double quotes. To fully support literal quotes in filters, both single and double quotes will no longer be removed from filter values.
- [17984](https://github.com/apache/superset/pull/17984): Default Flask SECRET_KEY has changed for security reasons. You should always override with your own secret. Set `PREVIOUS_SECRET_KEY` (ex: PREVIOUS_SECRET_KEY = "\2\1thisismyscretkey\1\2\\e\\y\\y\\h") with your previous key and use `superset re-encrypt-secrets` to rotate you current secrets
- [15254](https://github.com/apache/superset/pull/15254): Previously `QUERY_COST_FORMATTERS_BY_ENGINE`, `SQL_VALIDATORS_BY_ENGINE` and `SCHEDULED_QUERIES` were expected to be defined in the feature flag dictionary in the `config.py` file. These should now be defined as a top-level config, with the feature flag dictionary being reserved for boolean only values.
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ ADMIN_PASSWORD="admin"
# If Cypress run – overwrite the password for admin and export env variables
if [ "$CYPRESS_CONFIG" == "true" ]; then
ADMIN_PASSWORD="general"
export SUPERSET_CONFIG=tests.superset_test_config
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
export SUPERSET_TESTENV=true
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
fi
Expand Down
2 changes: 1 addition & 1 deletion scripts/python_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ superset init

echo "Running tests"

pytest --durations=0 --maxfail=1 --cov=superset "$@"
pytest --durations-min=2 --maxfail=1 --cov-report= --cov=superset "$@"
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { getChartAlias, Slice } from 'cypress/utils/vizPlugins';
import {
dashboardView,
editDashboardView,
nativeFilters,
} from 'cypress/support/directories';

/**
* Licensed to the Apache Software Foundation (ASF) under one
Expand All @@ -25,7 +30,13 @@ export const testItems = {
dashboard: 'Cypress Sales Dashboard',
dataset: 'Vehicle Sales',
chart: 'Cypress chart',
newChart: 'New Cypress Chart',
createdDashboard: 'New Dashboard',
defaultNameDashboard: '[ untitled dashboard ]',
newDashboardTitle: `Test dashboard [NEW TEST]`,
bulkFirstNameDashboard: 'First Dash',
bulkSecondNameDashboard: 'Second Dash',
worldBanksDataCopy: `World Bank's Data [copy]`,
};

export const CHECK_DASHBOARD_FAVORITE_ENDPOINT =
Expand Down Expand Up @@ -133,3 +144,112 @@ export function resize(selector: string) {
},
};
}

export function cleanUp() {
cy.deleteDashboardByName(testItems.dashboard);
cy.deleteDashboardByName(testItems.defaultNameDashboard);
cy.deleteDashboardByName('');
cy.deleteDashboardByName(testItems.newDashboardTitle);
cy.deleteDashboardByName(testItems.bulkFirstNameDashboard);
cy.deleteDashboardByName(testItems.bulkSecondNameDashboard);
cy.deleteDashboardByName(testItems.createdDashboard);
cy.deleteDashboardByName(testItems.worldBanksDataCopy);
cy.deleteChartByName(testItems.chart);
cy.deleteChartByName(testItems.newChart);
}

/** ************************************************************************
* Clicks on new filter button
* @returns {None}
* @summary helper for adding new filter
************************************************************************* */
export function clickOnAddFilterInModal() {
return cy
.get(nativeFilters.addFilterButton.button)
.first()
.click()
.then(() => {
cy.get(nativeFilters.addFilterButton.dropdownItem)
.contains('Filter')
.click({ force: true });
});
}

/** ************************************************************************
* Fills value native filter form with basic information
* @param {string} name name for filter
* @param {string} dataset which dataset should be used
* @param {string} filterColumn which column should be used
* @returns {None}
* @summary helper for filling value native filter form
************************************************************************* */
export function fillValueNativeFilterForm(
name: string,
dataset: string,
filterColumn: string,
) {
cy.get(nativeFilters.modal.container)
.find(nativeFilters.filtersPanel.filterName)
.last()
.click({ scrollBehavior: false })
.type(name, { scrollBehavior: false });
cy.get(nativeFilters.modal.container)
.find(nativeFilters.filtersPanel.datasetName)
.last()
.click({ scrollBehavior: false })
.type(`${dataset}{enter}`, { scrollBehavior: false });
cy.get(nativeFilters.silentLoading).should('not.exist');
cy.get(nativeFilters.filtersPanel.filterInfoInput)
.last()
.should('be.visible')
.click({ force: true });
cy.get(nativeFilters.filtersPanel.filterInfoInput).last().type(filterColumn);
cy.get(nativeFilters.filtersPanel.inputDropdown)
.should('be.visible', { timeout: 20000 })
.last()
.click();
}
/** ************************************************************************
* Get native filter placeholder e.g 9 options
* @param {number} index which input it fills
* @returns cy object for assertions
* @summary helper for getting placeholder value
************************************************************************* */
export function getNativeFilterPlaceholderWithIndex(index: number) {
return cy.get(nativeFilters.filtersPanel.columnEmptyInput).eq(index);
}

/** ************************************************************************
* Apply native filter value from dashboard view
* @param {number} index which input it fills
* @param {string} value what is filter value
* @returns {null}
* @summary put value to nth native filter input in view
************************************************************************* */
export function applyNativeFilterValueWithIndex(index: number, value: string) {
cy.get(nativeFilters.filterFromDashboardView.filterValueInput)
.eq(index)
.parent()
.should('be.visible', { timeout: 10000 })
.type(`${value}{enter}`);
// click the title to dismiss shown options
cy.get(nativeFilters.filterFromDashboardView.filterName).eq(index).click();
}

/** ************************************************************************
* Fills parent filter input
* @param {number} index which input it fills
* @param {string} value on which filter it depends on
* @returns {null}
* @summary takes first or second input and modify the depends on filter value
************************************************************************* */
export function addParentFilterWithValue(index: number, value: string) {
return cy
.get(nativeFilters.filterConfigurationSections.displayedSection)
.within(() => {
cy.get('input[aria-label="Limit type"]')
.eq(index)
.click({ force: true })
.type(`${value}{enter}`, { delay: 30, force: true });
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@ import {
nativeFilters,
exploreView,
} from 'cypress/support/directories';
import { testItems } from './dashboard.helper';
import {
cleanUp,
testItems,
WORLD_HEALTH_CHARTS,
waitForChartLoad,
clickOnAddFilterInModal,
fillValueNativeFilterForm,
getNativeFilterPlaceholderWithIndex,
addParentFilterWithValue,
applyNativeFilterValueWithIndex,
} from './dashboard.helper';
import { DASHBOARD_LIST } from '../dashboard_list/dashboard_list.helper';
import { CHART_LIST } from '../chart_list/chart_list.helper';
import { FORM_DATA_DEFAULTS } from '../explore/visualizations/shared.helper';
Expand All @@ -39,21 +49,27 @@ const milliseconds = new Date().getTime();
const dashboard = `Test Dashboard${milliseconds}`;

describe('Nativefilters Sanity test', () => {
before(() => {
beforeEach(() => {
cy.login();
cleanUp();
cy.intercept('/api/v1/dashboard/?q=**').as('dashboardsList');
cy.intercept('POST', '**/copy_dash/*').as('copy');
cy.intercept('/api/v1/dashboard/*').as('dashboard');
cy.request(
'api/v1/dashboard/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:100)',
).then(xhr => {
const dashboards = xhr.body.result;
cy.intercept('GET', '**/api/v1/dataset/**').as('datasetLoad');
cy.intercept('**/api/v1/dashboard/?q=**').as('dashboardsList');
cy.visit('dashboard/list/');
cy.contains('Actions');
cy.wait('@dashboardsList').then(xhr => {
const dashboards = xhr.response?.body.result;
/* eslint-disable no-unused-expressions */
expect(dashboards).not.to.be.undefined;
const worldBankDashboard = dashboards.find(
(d: { dashboard_title: string }) =>
d.dashboard_title === "World Bank's Data",
);
cy.visit(worldBankDashboard.url);
});
WORLD_HEALTH_CHARTS.forEach(waitForChartLoad);
cy.get(dashboardView.threeDotsMenuIcon).should('be.visible').click();
cy.get(dashboardView.saveAsMenuOption).should('be.visible').click();
cy.get(dashboardView.saveModal.dashboardNameInput)
Expand All @@ -65,19 +81,10 @@ describe('Nativefilters Sanity test', () => {
.its('response.statusCode')
.should('eq', 200);
});
beforeEach(() => {
cy.login();
cy.request(
'api/v1/dashboard/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:100)',
).then(xhr => {
const dashboards = xhr.body.result;
const testDashboard = dashboards.find(
(d: { dashboard_title: string }) =>
d.dashboard_title === testItems.dashboard,
);
cy.visit(testDashboard.url);
});
afterEach(() => {
cleanUp();
});

it('User can expand / retract native filter sidebar on a dashboard', () => {
cy.get(nativeFilters.createFilterButton).should('not.exist');
cy.get(nativeFilters.filterFromDashboardView.expand)
Expand Down Expand Up @@ -390,15 +397,6 @@ describe('Nativefilters Sanity test', () => {
cy.get('.line').within(() => {
cy.contains('United States').should('be.visible');
});

// clean up the default setting
cy.get(nativeFilters.filterFromDashboardView.expand).click({ force: true });
cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click();
cy.contains('Filter has default value').click();
cy.get(nativeFilters.modal.footer)
.find(nativeFilters.modal.saveButton)
.should('be.visible')
.click({ force: true });
});

it('User can create a time grain filter', () => {
Expand Down Expand Up @@ -565,6 +563,51 @@ describe('Nativefilters Sanity test', () => {
.should('be.visible', { timeout: 40000 })
.contains('country_name');
});

it('User can create parent filters using "Values are dependent on other filters"', () => {
cy.get(nativeFilters.filterFromDashboardView.expand)
.should('be.visible')
.click({ force: true });
cy.get(nativeFilters.filterFromDashboardView.createFilterButton).click();
// Create parent filter 'region'.
fillValueNativeFilterForm('region', 'wb_health_population', 'region');
// Create filter 'country_name' depend on region filter.
clickOnAddFilterInModal();
fillValueNativeFilterForm(
'country_name',
'wb_health_population',
'country_name',
);
cy.get(nativeFilters.filterConfigurationSections.displayedSection).within(
() => {
cy.contains('Values are dependent on other filters')
.should('be.visible')
.click();
},
);
addParentFilterWithValue(0, 'region');
cy.wait(1000);
cy.get(nativeFilters.modal.footer)
.contains('Save')
.should('be.visible')
.click();
// Validate both filter in dashboard view.
WORLD_HEALTH_CHARTS.forEach(waitForChartLoad);
['region', 'country_name'].forEach(it => {
cy.get(nativeFilters.filterFromDashboardView.filterName)
.contains(it)
.should('be.visible');
});
getNativeFilterPlaceholderWithIndex(1)
.invoke('text')
.should('equal', '214 options', { timeout: 20000 });
// apply first filter value and validate 2nd filter is depden on 1st filter.
applyNativeFilterValueWithIndex(0, 'East Asia & Pacific');

getNativeFilterPlaceholderWithIndex(0).should('have.text', '36 options', {
timeout: 20000,
});
});
});

xdescribe('Nativefilters', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ describe('Test datatable', () => {
it('Datapane loads view samples', () => {
cy.get('[data-test="data-tab"]').click();
cy.contains('View samples').click();
cy.get('[data-test="row-count-label"]').contains('10k rows retrieved');
cy.get('[data-test="row-count-label"]').contains('1k rows retrieved');
cy.get('.ant-empty-description').should('not.exist');
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ describe('SqlLab query panel', () => {
const sampleResponse = {
status: 'success',
data: [{ '?column?': 1 }],
columns: [{ name: '?column?', type: 'INT', is_date: false }],
selected_columns: [{ name: '?column?', type: 'INT', is_date: false }],
columns: [{ name: '?column?', type: 'INT', is_dttm: false }],
selected_columns: [{ name: '?column?', type: 'INT', is_dttm: false }],
expanded_columns: [],
};

Expand Down
14 changes: 14 additions & 0 deletions superset-frontend/cypress-base/cypress/support/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ declare namespace Cypress {
querySubstring?: string | RegExp;
chartSelector?: JQuery.Selector;
}): cy;

/**
* Get
*/
getDashboards(): cy;
getCharts(): cy;

/**
* Delete
*/
deleteDashboard(id: number): cy;
deleteDashboardByName(name: string): cy;
deleteChartByName(name: string): cy;
deleteChart(id: number): cy;
}
}

Expand Down
Loading

0 comments on commit 8c0ad91

Please sign in to comment.