diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/controls.js b/superset-frontend/cypress-base/cypress/integration/dashboard/controls.js deleted file mode 100644 index aa04410173af0..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/controls.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; -import readResponseBlob from '../../utils/readResponseBlob'; - -export default () => - describe('top-level controls', () => { - const sliceRequests = []; - const forceRefreshRequests = []; - let mapId; - - 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; - mapId = dashboard.slices.find( - slice => slice.form_data.viz_type === 'world_map', - ).slice_id; - - dashboard.slices.forEach(slice => { - const sliceRequest = `getJson_${slice.slice_id}`; - sliceRequests.push(`@${sliceRequest}`); - const formData = `{"slice_id":${slice.slice_id}}`; - cy.route('POST', `/superset/explore_json/?form_data=${formData}`).as( - sliceRequest, - ); - - const forceRefresh = `postJson_${slice.slice_id}_force`; - forceRefreshRequests.push(`@${forceRefresh}`); - cy.route( - 'POST', - `/superset/explore_json/?form_data={"slice_id":${slice.slice_id}}&force=true`, - ).as(forceRefresh); - }); - }); - }); - afterEach(() => { - sliceRequests.length = 0; - forceRefreshRequests.length = 0; - }); - - it.skip('should allow chart level refresh', () => { - cy.wait(sliceRequests); - cy.get('.grid-container .world_map').should('be.exist'); - cy.get(`#slice_${mapId}-controls`).click(); - cy.get(`#slice_${mapId}-controls`) - .next() - .find('.refresh-tooltip') - .trigger('click', { force: true }); - - // not allow dashboard level force refresh when any chart is loading - cy.get('#save-dash-split-button').trigger('click', { force: true }); - cy.contains('Force refresh dashboard') - .parent() - .should('have.class', 'disabled'); - // not allow chart level force refresh when it is loading - cy.get(`#slice_${mapId}-controls`) - .next() - .find('.refresh-tooltip') - .parent() - .parent() - .should('have.class', 'disabled'); - - cy.wait(`@postJson_${mapId}_force`); - cy.get('#save-dash-split-button').trigger('click'); - cy.contains('Force refresh dashboard') - .parent() - .not('have.class', 'disabled'); - }); - - it.skip('should allow dashboard level force refresh', () => { - // when charts are not start loading, for example, under a secondary tab, - // should allow force refresh - cy.get('#save-dash-split-button').trigger('click'); - cy.contains('Force refresh dashboard') - .parent() - .not('have.class', 'disabled'); - - // wait the all dash finish loading. - cy.wait(sliceRequests); - cy.get('#save-dash-split-button').trigger('click'); - cy.contains('Force refresh dashboard').trigger('click', { force: true }); - cy.get('#save-dash-split-button').trigger('click'); - cy.contains('Force refresh dashboard') - .parent() - .should('have.class', 'disabled'); - - // wait all charts force refreshed - cy.wait(forceRefreshRequests).then(xhrs => { - // is_cached in response should be false - xhrs.forEach(xhr => { - readResponseBlob(xhr.response.body).then(responseBody => { - expect(responseBody.is_cached).to.equal(false); - }); - }); - }); - - cy.get('#save-dash-split-button').trigger('click'); - cy.contains('Force refresh dashboard') - .parent() - .not('have.class', 'disabled'); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/controls.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/controls.test.js new file mode 100644 index 0000000000000..12f1b3a9d9c9b --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/controls.test.js @@ -0,0 +1,122 @@ +/** + * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; +import readResponseBlob from '../../utils/readResponseBlob'; + +describe('Dashboard top-level controls', () => { + const sliceRequests = []; + const forceRefreshRequests = []; + let mapId; + + 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; + mapId = dashboard.slices.find( + slice => slice.form_data.viz_type === 'world_map', + ).slice_id; + + dashboard.slices.forEach(slice => { + const sliceRequest = `getJson_${slice.slice_id}`; + sliceRequests.push(`@${sliceRequest}`); + const formData = `{"slice_id":${slice.slice_id}}`; + cy.route('POST', `/superset/explore_json/?form_data=${formData}`).as( + sliceRequest, + ); + + const forceRefresh = `postJson_${slice.slice_id}_force`; + forceRefreshRequests.push(`@${forceRefresh}`); + cy.route( + 'POST', + `/superset/explore_json/?form_data={"slice_id":${slice.slice_id}}&force=true`, + ).as(forceRefresh); + }); + }); + }); + afterEach(() => { + sliceRequests.length = 0; + forceRefreshRequests.length = 0; + }); + + it.skip('should allow chart level refresh', () => { + cy.wait(sliceRequests); + cy.get('.grid-container .world_map').should('be.exist'); + cy.get(`#slice_${mapId}-controls`).click(); + cy.get(`#slice_${mapId}-controls`) + .next() + .find('.refresh-tooltip') + .trigger('click', { force: true }); + + // not allow dashboard level force refresh when any chart is loading + cy.get('#save-dash-split-button').trigger('click', { force: true }); + cy.contains('Force refresh dashboard') + .parent() + .should('have.class', 'disabled'); + // not allow chart level force refresh when it is loading + cy.get(`#slice_${mapId}-controls`) + .next() + .find('.refresh-tooltip') + .parent() + .parent() + .should('have.class', 'disabled'); + + cy.wait(`@postJson_${mapId}_force`); + cy.get('#save-dash-split-button').trigger('click'); + cy.contains('Force refresh dashboard') + .parent() + .not('have.class', 'disabled'); + }); + + it.skip('should allow dashboard level force refresh', () => { + // when charts are not start loading, for example, under a secondary tab, + // should allow force refresh + cy.get('#save-dash-split-button').trigger('click'); + cy.contains('Force refresh dashboard') + .parent() + .not('have.class', 'disabled'); + + // wait the all dash finish loading. + cy.wait(sliceRequests); + cy.get('#save-dash-split-button').trigger('click'); + cy.contains('Force refresh dashboard').trigger('click', { force: true }); + cy.get('#save-dash-split-button').trigger('click'); + cy.contains('Force refresh dashboard') + .parent() + .should('have.class', 'disabled'); + + // wait all charts force refreshed + cy.wait(forceRefreshRequests).then(xhrs => { + // is_cached in response should be false + xhrs.forEach(xhr => { + readResponseBlob(xhr.response.body).then(responseBody => { + expect(responseBody.is_cached).to.equal(false); + }); + }); + }); + + cy.get('#save-dash-split-button').trigger('click'); + cy.contains('Force refresh dashboard') + .parent() + .not('have.class', 'disabled'); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.js b/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.js deleted file mode 100644 index 821c94fcf12d9..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; - -export default () => - describe('edit mode', () => { - beforeEach(() => { - cy.server(); - cy.login(); - cy.visit(WORLD_HEALTH_DASHBOARD); - cy.get('.dashboard-header').contains('Edit dashboard').click(); - }); - - it('remove, and add chart flow', () => { - // wait for box plot to appear - cy.get('.grid-container .box_plot'); - - 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 div.grid-row.background--transparent') - .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-frontend/cypress-base/cypress/integration/dashboard/edit_mode.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.test.js new file mode 100644 index 0000000000000..b72535496db14 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.test.js @@ -0,0 +1,75 @@ +/** + * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; + +describe('Dashboard edit mode', () => { + beforeEach(() => { + cy.server(); + cy.login(); + cy.visit(WORLD_HEALTH_DASHBOARD); + cy.get('.dashboard-header').contains('Edit dashboard').click(); + }); + + it('remove, and add chart flow', () => { + // wait for box plot to appear + cy.get('.grid-container .box_plot'); + + 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 div.grid-row.background--transparent') + .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-frontend/cypress-base/cypress/integration/dashboard/fav_star.js b/superset-frontend/cypress-base/cypress/integration/dashboard/fav_star.js deleted file mode 100644 index 00dc19c9dc87a..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/fav_star.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * 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 { - WORLD_HEALTH_DASHBOARD, - CHECK_DASHBOARD_FAVORITE_ENDPOINT, -} from './dashboard.helper'; - -export default () => - describe('favorite dashboard', () => { - let isFavoriteDashboard = false; - - beforeEach(() => { - cy.server(); - cy.login(); - - cy.route(CHECK_DASHBOARD_FAVORITE_ENDPOINT).as('countFavStar'); - cy.visit(WORLD_HEALTH_DASHBOARD); - - 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'); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/fav_star.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/fav_star.test.js new file mode 100644 index 0000000000000..4b8b11f369f13 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/fav_star.test.js @@ -0,0 +1,62 @@ +/** + * 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 { + WORLD_HEALTH_DASHBOARD, + CHECK_DASHBOARD_FAVORITE_ENDPOINT, +} from './dashboard.helper'; + +describe('Dashboard add to favorite', () => { + let isFavoriteDashboard = false; + + beforeEach(() => { + cy.server(); + cy.login(); + + cy.route(CHECK_DASHBOARD_FAVORITE_ENDPOINT).as('countFavStar'); + cy.visit(WORLD_HEALTH_DASHBOARD); + + 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'); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/filter.js b/superset-frontend/cypress-base/cypress/integration/dashboard/filter.js deleted file mode 100644 index 11edd8694ed27..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/filter.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; - -export default () => - describe('dashboard filter', () => { - let filterId; - let aliases; - - const getAlias = id => { - return `@slice_${id}`; - }; - - 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 sliceIds = dashboard.slices.map(slice => slice.slice_id); - filterId = dashboard.slices.find( - slice => slice.form_data.viz_type === 'filter_box', - ).slice_id; - aliases = sliceIds.map(id => { - const alias = getAlias(id); - const url = `/superset/explore_json/?*{"slice_id":${id}}*`; - cy.route('POST', url).as(alias.slice(1)); - return alias; - }); - - // wait the initial page load requests - cy.wait(aliases); - }); - }); - - it('should apply filter', () => { - cy.get('.Select__control input[type=text]').first().focus(); - - // should open the filter indicator - cy.get('.filter-indicator.active') - .should('be.visible') - .should(nodes => { - expect(nodes).to.have.length(9); - }); - - cy.get('.Select__control input[type=text]').first().blur(); - - // should hide the filter indicator - cy.get('.filter-indicator') - .not('.active') - .should(nodes => { - expect(nodes).to.have.length(18); - }); - - cy.get('.Select__control input[type=text]') - .first() - .focus({ force: true }) - .type('So', { force: true }); - - cy.get('.Select__menu').first().contains('Create "So"'); - - // Somehow Input loses focus after typing "So" while in Cypress, so - // we refocus the input again here. The is not happening in real life. - cy.get('.Select__control input[type=text]') - .first() - .focus({ force: true }) - .type('uth Asia{enter}', { force: true }); - - // by default, need to click Apply button to apply filter - cy.get('.filter_box button').click({ force: true }); - - // wait again after applied filters - cy.wait(aliases.filter(x => x !== getAlias(filterId))).then(requests => { - requests.forEach(xhr => { - const requestFormData = xhr.request.body; - const requestParams = JSON.parse(requestFormData.get('form_data')); - expect(requestParams.extra_filters[0]).deep.eq({ - col: 'region', - op: 'in', - val: ['South Asia'], - }); - }); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/filter.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/filter.test.js new file mode 100644 index 0000000000000..daa4d76a83898 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/filter.test.js @@ -0,0 +1,103 @@ +/** + * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; + +describe('Dashboard filter', () => { + let filterId; + let aliases; + + const getAlias = id => { + return `@slice_${id}`; + }; + + 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 sliceIds = dashboard.slices.map(slice => slice.slice_id); + filterId = dashboard.slices.find( + slice => slice.form_data.viz_type === 'filter_box', + ).slice_id; + aliases = sliceIds.map(id => { + const alias = getAlias(id); + const url = `/superset/explore_json/?*{"slice_id":${id}}*`; + cy.route('POST', url).as(alias.slice(1)); + return alias; + }); + + // wait the initial page load requests + cy.wait(aliases); + }); + }); + + it('should apply filter', () => { + cy.get('.Select__control input[type=text]').first().focus(); + + // should open the filter indicator + cy.get('.filter-indicator.active') + .should('be.visible') + .should(nodes => { + expect(nodes).to.have.length(9); + }); + + cy.get('.Select__control input[type=text]').first().blur(); + + // should hide the filter indicator + cy.get('.filter-indicator') + .not('.active') + .should(nodes => { + expect(nodes).to.have.length(18); + }); + + cy.get('.Select__control input[type=text]') + .first() + .focus({ force: true }) + .type('So', { force: true }); + + cy.get('.Select__menu').first().contains('Create "So"'); + + // Somehow Input loses focus after typing "So" while in Cypress, so + // we refocus the input again here. The is not happening in real life. + cy.get('.Select__control input[type=text]') + .first() + .focus({ force: true }) + .type('uth Asia{enter}', { force: true }); + + // by default, need to click Apply button to apply filter + cy.get('.filter_box button').click({ force: true }); + + // wait again after applied filters + cy.wait(aliases.filter(x => x !== getAlias(filterId))).then(requests => { + requests.forEach(xhr => { + const requestFormData = xhr.request.body; + const requestParams = JSON.parse(requestFormData.get('form_data')); + expect(requestParams.extra_filters[0]).deep.eq({ + col: 'region', + op: 'in', + val: ['South Asia'], + }); + }); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/load.js b/superset-frontend/cypress-base/cypress/integration/dashboard/load.js deleted file mode 100644 index 2d48f84b283ad..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/load.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * 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 readResponseBlob from '../../utils/readResponseBlob'; -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}`; - const formData = `{"slice_id":${slice.slice_id}}`; - cy.route('POST', `/superset/explore_json/?*${formData}*`).as(alias); - aliases.push(`@${alias}`); - }); - }); - }); - - it('should load dashboard', () => { - // wait and verify one-by-one - cy.wait(aliases).then(requests => { - return Promise.all( - requests.map(async xhr => { - expect(xhr.status).to.eq(200); - const responseBody = await readResponseBlob(xhr.response.body); - expect(responseBody).to.have.property('errors'); - expect(responseBody.errors.length).to.eq(0); - const sliceId = responseBody.form_data.slice_id; - cy.get(`#chart-id-${sliceId}`).should('be.visible'); - }), - ); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/load.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/load.test.js new file mode 100644 index 0000000000000..3a5073441cd85 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/load.test.js @@ -0,0 +1,59 @@ +/** + * 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 readResponseBlob from '../../utils/readResponseBlob'; +import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; + +describe('Dashboard 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}`; + const formData = `{"slice_id":${slice.slice_id}}`; + cy.route('POST', `/superset/explore_json/?*${formData}*`).as(alias); + aliases.push(`@${alias}`); + }); + }); + }); + + it('should load dashboard', () => { + // wait and verify one-by-one + cy.wait(aliases).then(requests => { + return Promise.all( + requests.map(async xhr => { + expect(xhr.status).to.eq(200); + const responseBody = await readResponseBlob(xhr.response.body); + expect(responseBody).to.have.property('errors'); + expect(responseBody.errors.length).to.eq(0); + const sliceId = responseBody.form_data.slice_id; + cy.get(`#chart-id-${sliceId}`).should('be.visible'); + }), + ); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/save.js b/superset-frontend/cypress-base/cypress/integration/dashboard/save.js deleted file mode 100644 index a4611c7207796..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/save.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * 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 readResponseBlob from '../../utils/readResponseBlob'; -import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; - -export default () => - describe('save', () => { - let dashboardId; - let boxplotChartId; - - 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; - dashboardId = dashboard.id; - boxplotChartId = dashboard.slices.find( - slice => slice.form_data.viz_type === 'box_plot', - ).slice_id; - - cy.route('POST', `/superset/copy_dash/${dashboardId}/`).as( - 'copyRequest', - ); - }); - - cy.get('#save-dash-split-button').trigger('click', { force: true }); - cy.contains('Save as').trigger('click', { force: true }); - cy.get('.modal-footer') - .contains('Save') - .trigger('click', { force: true }); - }); - - it('should save as new dashboard', () => { - cy.wait('@copyRequest').then(xhr => { - expect(xhr.status).to.eq(200); - readResponseBlob(xhr.response.body).then(json => { - expect(json.id).to.be.gt(dashboardId); - }); - }); - }); - - it('should save/overwrite dashboard', () => { - // should have box_plot chart - cy.get('.grid-container .box_plot', { timeout: 5000 }); // wait for 5 secs - - // remove box_plot chart from dashboard - cy.get('.dashboard-header') - .contains('Edit dashboard') - .trigger('click', { force: true }); - cy.get('.fa.fa-trash').last().trigger('click', { force: true }); - cy.get('.grid-container .box_plot').should('not.exist'); - - cy.route('POST', '/superset/save_dash/**/').as('saveRequest'); - cy.get('.dashboard-header') - .contains('Save changes') - .trigger('click', { force: true }); - - // go back to view mode - cy.wait('@saveRequest'); - cy.get('.dashboard-header').contains('Edit dashboard'); - cy.get('.grid-container .box_plot').should('not.exist'); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js new file mode 100644 index 0000000000000..8f7069ccb2c9c --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js @@ -0,0 +1,77 @@ +/** + * 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 readResponseBlob from '../../utils/readResponseBlob'; +import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; + +describe('Dashboard save action', () => { + let dashboardId; + let boxplotChartId; + + 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; + dashboardId = dashboard.id; + boxplotChartId = dashboard.slices.find( + slice => slice.form_data.viz_type === 'box_plot', + ).slice_id; + + cy.route('POST', `/superset/copy_dash/${dashboardId}/`).as('copyRequest'); + }); + + cy.get('#save-dash-split-button').trigger('click', { force: true }); + cy.contains('Save as').trigger('click', { force: true }); + cy.get('.modal-footer').contains('Save').trigger('click', { force: true }); + }); + + it('should save as new dashboard', () => { + cy.wait('@copyRequest').then(xhr => { + expect(xhr.status).to.eq(200); + readResponseBlob(xhr.response.body).then(json => { + expect(json.id).to.be.gt(dashboardId); + }); + }); + }); + + it('should save/overwrite dashboard', () => { + // should have box_plot chart + cy.get('.grid-container .box_plot', { timeout: 5000 }); // wait for 5 secs + + // remove box_plot chart from dashboard + cy.get('.dashboard-header') + .contains('Edit dashboard') + .trigger('click', { force: true }); + cy.get('.fa.fa-trash').last().trigger('click', { force: true }); + cy.get('.grid-container .box_plot').should('not.exist'); + + cy.route('POST', '/superset/save_dash/**/').as('saveRequest'); + cy.get('.dashboard-header') + .contains('Save changes') + .trigger('click', { force: true }); + + // go back to view mode + cy.wait('@saveRequest'); + cy.get('.dashboard-header').contains('Edit dashboard'); + cy.get('.grid-container .box_plot').should('not.exist'); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.js b/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.js deleted file mode 100644 index 130609fba2793..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * 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 } from './dashboard.helper'; - -export default () => - describe('tabs', () => { - let filterId; - let treemapId; - let linechartId; - let boxplotId; - let dashboardId; - - // cypress can not handle window.scrollTo - // https://github.com/cypress-io/cypress/issues/2761 - // add this exception handler to pass test - const handleException = () => { - // return false to prevent the error from - // failing this test - cy.on('uncaught:exception', () => false); - }; - - beforeEach(() => { - cy.server(); - cy.login(); - - cy.visit(TABBED_DASHBOARD); - - cy.get('#app').then(data => { - const bootstrapData = JSON.parse(data[0].dataset.bootstrap); - const dashboard = bootstrapData.dashboard_data; - dashboardId = dashboard.id; - filterId = dashboard.slices.find( - slice => slice.form_data.viz_type === 'filter_box', - ).slice_id; - boxplotId = dashboard.slices.find( - slice => slice.form_data.viz_type === 'box_plot', - ).slice_id; - treemapId = dashboard.slices.find( - slice => slice.form_data.viz_type === 'treemap', - ).slice_id; - linechartId = dashboard.slices.find( - slice => slice.form_data.viz_type === 'line', - ).slice_id; - - const filterFormdata = { - slice_id: filterId, - }; - const filterRequest = `/superset/explore_json/?form_data=${JSON.stringify( - filterFormdata, - )}&dashboard_id=${dashboardId}`; - cy.route('POST', filterRequest).as('filterRequest'); - - const treemapFormdata = { - slice_id: treemapId, - }; - const treemapRequest = `/superset/explore_json/?form_data=${JSON.stringify( - treemapFormdata, - )}&dashboard_id=${dashboardId}`; - cy.route('POST', treemapRequest).as('treemapRequest'); - - const linechartFormdata = { - slice_id: linechartId, - }; - const linechartRequest = `/superset/explore_json/?form_data=${JSON.stringify( - linechartFormdata, - )}&dashboard_id=${dashboardId}`; - cy.route('POST', linechartRequest).as('linechartRequest'); - - const boxplotFormdata = { - slice_id: boxplotId, - }; - const boxplotRequest = `/superset/explore_json/?form_data=${JSON.stringify( - boxplotFormdata, - )}&dashboard_id=${dashboardId}`; - cy.route('POST', boxplotRequest).as('boxplotRequest'); - }); - }); - - it('should load charts when tab is visible', () => { - // landing in first tab, should see 2 charts - cy.wait('@filterRequest'); - cy.get('.grid-container .filter_box').should('be.exist'); - cy.wait('@treemapRequest'); - cy.get('.grid-container .treemap').should('be.exist'); - cy.get('.grid-container .box_plot').should('not.be.exist'); - cy.get('.grid-container .line').should('not.be.exist'); - - // click row level tab, see 1 more chart - cy.get('.tab-content ul.nav.nav-tabs li') - .last() - .find('.editable-title input') - .click(); - cy.wait('@linechartRequest'); - cy.get('.grid-container .line').should('be.exist'); - - // click top level tab, see 1 more chart - handleException(); - cy.get('.dashboard-component-tabs') - .first() - .find('ul.nav.nav-tabs li') - .last() - .find('.editable-title input') - .click(); - - // should exist a visible box_plot element - cy.get('.grid-container .box_plot'); - }); - - it('should send new queries when tab becomes visible', () => { - // landing in first tab - cy.wait('@filterRequest'); - cy.wait('@treemapRequest'); - - // apply filter - cy.get('.Select__control').first().should('be.visible'); - cy.get('.Select__control').first().click({ force: true }); - cy.get('.Select__control input[type=text]') - .first() - .should('be.visible') - .type('South Asia{enter}', { force: true }); - - // send new query from same tab - cy.wait('@treemapRequest').then(xhr => { - const requestFormData = xhr.request.body; - const requestParams = JSON.parse(requestFormData.get('form_data')); - expect(requestParams.extra_filters[0]).deep.eq({ - col: 'region', - op: 'in', - val: ['South Asia'], - }); - }); - - // click row level tab, send 1 more query - cy.get('.tab-content ul.nav.nav-tabs li').last().click(); - cy.wait('@linechartRequest').then(xhr => { - const requestFormData = xhr.request.body; - const requestParams = JSON.parse(requestFormData.get('form_data')); - expect(requestParams.extra_filters[0]).deep.eq({ - col: 'region', - op: 'in', - val: ['South Asia'], - }); - }); - - // click top level tab, send 1 more query - handleException(); - cy.get('.dashboard-component-tabs') - .first() - .find('ul.nav.nav-tabs li') - .last() - .find('.editable-title input') - .click(); - - cy.wait('@boxplotRequest').then(xhr => { - const requestFormData = xhr.request.body; - const requestParams = JSON.parse(requestFormData.get('form_data')); - expect(requestParams.extra_filters[0]).deep.eq({ - col: 'region', - op: 'in', - val: ['South Asia'], - }); - }); - - // navigate to filter and clear filter - cy.get('.dashboard-component-tabs') - .first() - .find('ul.nav.nav-tabs li') - .first() - .click(); - cy.get('.tab-content ul.nav.nav-tabs li') - .first() - .should('be.visible') - .click(); - cy.get('.Select__clear-indicator').click(); - - // trigger 1 new query - cy.wait('@treemapRequest'); - - // make sure query API not requested multiple times - cy.on('fail', err => { - expect(err.message).to.include('timed out waiting'); - return false; - }); - - cy.wait('@boxplotRequest', { timeout: 1000 }).then(() => { - throw new Error('Unexpected API call.'); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.test.js new file mode 100644 index 0000000000000..e4dd0d0f3f9ea --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.test.js @@ -0,0 +1,204 @@ +/** + * 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 } from './dashboard.helper'; + +describe('Dashboard tabs', () => { + let filterId; + let treemapId; + let linechartId; + let boxplotId; + let dashboardId; + + // cypress can not handle window.scrollTo + // https://github.com/cypress-io/cypress/issues/2761 + // add this exception handler to pass test + const handleException = () => { + // return false to prevent the error from + // failing this test + cy.on('uncaught:exception', () => false); + }; + + beforeEach(() => { + cy.server(); + cy.login(); + + cy.visit(TABBED_DASHBOARD); + + cy.get('#app').then(data => { + const bootstrapData = JSON.parse(data[0].dataset.bootstrap); + const dashboard = bootstrapData.dashboard_data; + dashboardId = dashboard.id; + filterId = dashboard.slices.find( + slice => slice.form_data.viz_type === 'filter_box', + ).slice_id; + boxplotId = dashboard.slices.find( + slice => slice.form_data.viz_type === 'box_plot', + ).slice_id; + treemapId = dashboard.slices.find( + slice => slice.form_data.viz_type === 'treemap', + ).slice_id; + linechartId = dashboard.slices.find( + slice => slice.form_data.viz_type === 'line', + ).slice_id; + + const filterFormdata = { + slice_id: filterId, + }; + const filterRequest = `/superset/explore_json/?form_data=${JSON.stringify( + filterFormdata, + )}&dashboard_id=${dashboardId}`; + cy.route('POST', filterRequest).as('filterRequest'); + + const treemapFormdata = { + slice_id: treemapId, + }; + const treemapRequest = `/superset/explore_json/?form_data=${JSON.stringify( + treemapFormdata, + )}&dashboard_id=${dashboardId}`; + cy.route('POST', treemapRequest).as('treemapRequest'); + + const linechartFormdata = { + slice_id: linechartId, + }; + const linechartRequest = `/superset/explore_json/?form_data=${JSON.stringify( + linechartFormdata, + )}&dashboard_id=${dashboardId}`; + cy.route('POST', linechartRequest).as('linechartRequest'); + + const boxplotFormdata = { + slice_id: boxplotId, + }; + const boxplotRequest = `/superset/explore_json/?form_data=${JSON.stringify( + boxplotFormdata, + )}&dashboard_id=${dashboardId}`; + cy.route('POST', boxplotRequest).as('boxplotRequest'); + }); + }); + + it('should load charts when tab is visible', () => { + // landing in first tab, should see 2 charts + cy.wait('@filterRequest'); + cy.get('.grid-container .filter_box').should('be.exist'); + cy.wait('@treemapRequest'); + cy.get('.grid-container .treemap').should('be.exist'); + cy.get('.grid-container .box_plot').should('not.be.exist'); + cy.get('.grid-container .line').should('not.be.exist'); + + // click row level tab, see 1 more chart + cy.get('.tab-content ul.nav.nav-tabs li') + .last() + .find('.editable-title input') + .click(); + cy.wait('@linechartRequest'); + cy.get('.grid-container .line').should('be.exist'); + + // click top level tab, see 1 more chart + handleException(); + cy.get('.dashboard-component-tabs') + .first() + .find('ul.nav.nav-tabs li') + .last() + .find('.editable-title input') + .click(); + + // should exist a visible box_plot element + cy.get('.grid-container .box_plot'); + }); + + it('should send new queries when tab becomes visible', () => { + // landing in first tab + cy.wait('@filterRequest'); + cy.wait('@treemapRequest'); + + // apply filter + cy.get('.Select__control').first().should('be.visible'); + cy.get('.Select__control').first().click({ force: true }); + cy.get('.Select__control input[type=text]') + .first() + .should('be.visible') + .type('South Asia{enter}', { force: true }); + + // send new query from same tab + cy.wait('@treemapRequest').then(xhr => { + const requestFormData = xhr.request.body; + const requestParams = JSON.parse(requestFormData.get('form_data')); + expect(requestParams.extra_filters[0]).deep.eq({ + col: 'region', + op: 'in', + val: ['South Asia'], + }); + }); + + // click row level tab, send 1 more query + cy.get('.tab-content ul.nav.nav-tabs li').last().click(); + cy.wait('@linechartRequest').then(xhr => { + const requestFormData = xhr.request.body; + const requestParams = JSON.parse(requestFormData.get('form_data')); + expect(requestParams.extra_filters[0]).deep.eq({ + col: 'region', + op: 'in', + val: ['South Asia'], + }); + }); + + // click top level tab, send 1 more query + handleException(); + cy.get('.dashboard-component-tabs') + .first() + .find('ul.nav.nav-tabs li') + .last() + .find('.editable-title input') + .click(); + + cy.wait('@boxplotRequest').then(xhr => { + const requestFormData = xhr.request.body; + const requestParams = JSON.parse(requestFormData.get('form_data')); + expect(requestParams.extra_filters[0]).deep.eq({ + col: 'region', + op: 'in', + val: ['South Asia'], + }); + }); + + // navigate to filter and clear filter + cy.get('.dashboard-component-tabs') + .first() + .find('ul.nav.nav-tabs li') + .first() + .click(); + cy.get('.tab-content ul.nav.nav-tabs li') + .first() + .should('be.visible') + .click(); + cy.get('.Select__clear-indicator').click(); + + // trigger 1 new query + cy.wait('@treemapRequest'); + + // make sure query API not requested multiple times + cy.on('fail', err => { + expect(err.message).to.include('timed out waiting'); + return false; + }); + + cy.wait('@boxplotRequest', { timeout: 1000 }).then(() => { + throw new Error('Unexpected API call.'); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.js b/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.js deleted file mode 100644 index 84b1a82c22d74..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; - -export default () => - describe('dashboard form data', () => { - const urlParams = { param1: '123', param2: 'abc' }; - let sliceIds = []; - let dashboardId; - - beforeEach(() => { - cy.server(); - cy.login(); - - cy.visit(WORLD_HEALTH_DASHBOARD, { qs: urlParams }); - - cy.get('#app').then(data => { - const bootstrapData = JSON.parse(data[0].dataset.bootstrap); - const dashboard = bootstrapData.dashboard_data; - dashboardId = dashboard.id; - sliceIds = dashboard.slices.map(slice => slice.slice_id); - }); - }); - - it('should apply url params and queryFields to slice requests', () => { - const aliases = []; - sliceIds.forEach(id => { - const alias = `getJson_${id}`; - aliases.push(`@${alias}`); - cy.route( - 'POST', - `/superset/explore_json/?form_data={"slice_id":${id}}&dashboard_id=${dashboardId}`, - ).as(alias); - }); - - cy.wait(aliases).then(requests => { - requests.forEach(xhr => { - const requestFormData = xhr.request.body; - const requestParams = JSON.parse(requestFormData.get('form_data')); - expect(requestParams).to.have.property('queryFields'); - expect(requestParams.url_params).deep.eq(urlParams); - }); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.test.js new file mode 100644 index 0000000000000..04eec1a099728 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.test.js @@ -0,0 +1,60 @@ +/** + * 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 { WORLD_HEALTH_DASHBOARD } from './dashboard.helper'; + +describe('Dashboard form data', () => { + const urlParams = { param1: '123', param2: 'abc' }; + let sliceIds = []; + let dashboardId; + + beforeEach(() => { + cy.server(); + cy.login(); + + cy.visit(WORLD_HEALTH_DASHBOARD, { qs: urlParams }); + + cy.get('#app').then(data => { + const bootstrapData = JSON.parse(data[0].dataset.bootstrap); + const dashboard = bootstrapData.dashboard_data; + dashboardId = dashboard.id; + sliceIds = dashboard.slices.map(slice => slice.slice_id); + }); + }); + + it('should apply url params and queryFields to slice requests', () => { + const aliases = []; + sliceIds.forEach(id => { + const alias = `getJson_${id}`; + aliases.push(`@${alias}`); + cy.route( + 'POST', + `/superset/explore_json/?form_data={"slice_id":${id}}&dashboard_id=${dashboardId}`, + ).as(alias); + }); + + cy.wait(aliases).then(requests => { + requests.forEach(xhr => { + const requestFormData = xhr.request.body; + const requestParams = JSON.parse(requestFormData.get('form_data')); + expect(requestParams).to.have.property('queryFields'); + expect(requestParams.url_params).deep.eq(urlParams); + }); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/index.test.js b/superset-frontend/cypress-base/cypress/integration/explore/filter_box.test.js similarity index 53% rename from superset-frontend/cypress-base/cypress/integration/dashboard/index.test.js rename to superset-frontend/cypress-base/cypress/integration/explore/filter_box.test.js index b4ee364feb140..b9793b3ea88fc 100644 --- a/superset-frontend/cypress-base/cypress/integration/dashboard/index.test.js +++ b/superset-frontend/cypress-base/cypress/integration/explore/filter_box.test.js @@ -16,22 +16,27 @@ * specific language governing permissions and limitations * under the License. */ -import DashboardControlsTest from './controls'; -import DashboardEditModeTest from './edit_mode'; -import DashboardFavStarTest from './fav_star'; -import DashboardFilterTest from './filter'; -import DashboardLoadTest from './load'; -import DashboardSaveTest from './save'; -import DashboardTabsTest from './tabs'; -import DashboardFormDataTest from './url_params'; +import { FORM_DATA_DEFAULTS } from './visualizations/shared.helper'; -describe('Dashboard', () => { - DashboardControlsTest(); - DashboardEditModeTest(); - DashboardFavStarTest(); - DashboardFilterTest(); - DashboardLoadTest(); - DashboardSaveTest(); - DashboardTabsTest(); - DashboardFormDataTest(); +describe('Edit FilterBox Chart', () => { + const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'filter_box' }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work with default date filter', () => { + verify(VIZ_DEFAULTS); + // Filter box should default to having a date filter with no filter selected + cy.get('div.filter_box').within(() => { + cy.get('span').contains('No filter'); + }); + }); }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/area.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/area.js deleted file mode 100644 index 229b05b0dc106..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/area.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * 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 readResponseBlob from '../../../utils/readResponseBlob'; - -export default () => - describe('Area', () => { - const AREA_FORM_DATA = { - datasource: '2__table', - viz_type: 'area', - slice_id: 48, - granularity_sqla: 'year', - time_grain_sqla: 'P1D', - time_range: '1960-01-01 : now', - metrics: ['sum__SP_POP_TOTL'], - adhoc_filters: [], - groupby: [], - limit: '25', - order_desc: true, - contribution: false, - row_limit: 50000, - show_brush: 'auto', - show_legend: true, - line_interpolation: 'linear', - stacked_style: 'stack', - color_scheme: 'bnbColors', - rich_tooltip: true, - show_controls: false, - x_axis_label: '', - bottom_margin: 'auto', - x_ticks_layout: 'auto', - x_axis_format: 'smart_date', - x_axis_showminmax: false, - y_axis_format: '.3s', - y_log_scale: false, - rolling_type: 'None', - comparison_type: 'values', - annotation_layers: [], - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work without groupby', () => { - verify(AREA_FORM_DATA); - cy.get('.nv-area').should('have.length', 1); - }); - - it('should work with group by', () => { - verify({ - ...AREA_FORM_DATA, - groupby: ['region'], - }); - - cy.get('.nv-area').should('have.length', 7); - }); - - it('should work with groupby and filter', () => { - cy.visitChartByParams( - JSON.stringify({ - ...AREA_FORM_DATA, - groupby: ['region'], - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'region', - operator: 'in', - comparator: ['South Asia', 'North America'], - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_txje2ikiv6_wxmn0qwd1xo', - }, - ], - }), - ); - - cy.wait('@getJson').then(async xhr => { - cy.verifyResponseCodes(xhr); - - const responseBody = await readResponseBlob(xhr.response.body); - - // Make sure data is sorted correctly - const firstRow = responseBody.data[0].values; - const secondRow = responseBody.data[1].values; - expect(firstRow[firstRow.length - 1].y).to.be.greaterThan( - secondRow[secondRow.length - 1].y, - ); - cy.verifySliceContainer('svg'); - }); - cy.get('.nv-area').should('have.length', 2); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/area.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/area.test.js new file mode 100644 index 0000000000000..b3c1b1a2c8db6 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/area.test.js @@ -0,0 +1,114 @@ +/** + * 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 readResponseBlob from '../../../utils/readResponseBlob'; + +describe('Visualization > Area', () => { + const AREA_FORM_DATA = { + datasource: '2__table', + viz_type: 'area', + slice_id: 48, + granularity_sqla: 'year', + time_grain_sqla: 'P1D', + time_range: '1960-01-01 : now', + metrics: ['sum__SP_POP_TOTL'], + adhoc_filters: [], + groupby: [], + limit: '25', + order_desc: true, + contribution: false, + row_limit: 50000, + show_brush: 'auto', + show_legend: true, + line_interpolation: 'linear', + stacked_style: 'stack', + color_scheme: 'bnbColors', + rich_tooltip: true, + show_controls: false, + x_axis_label: '', + bottom_margin: 'auto', + x_ticks_layout: 'auto', + x_axis_format: 'smart_date', + x_axis_showminmax: false, + y_axis_format: '.3s', + y_log_scale: false, + rolling_type: 'None', + comparison_type: 'values', + annotation_layers: [], + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work without groupby', () => { + verify(AREA_FORM_DATA); + cy.get('.nv-area').should('have.length', 1); + }); + + it('should work with group by', () => { + verify({ + ...AREA_FORM_DATA, + groupby: ['region'], + }); + + cy.get('.nv-area').should('have.length', 7); + }); + + it('should work with groupby and filter', () => { + cy.visitChartByParams( + JSON.stringify({ + ...AREA_FORM_DATA, + groupby: ['region'], + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'region', + operator: 'in', + comparator: ['South Asia', 'North America'], + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_txje2ikiv6_wxmn0qwd1xo', + }, + ], + }), + ); + + cy.wait('@getJson').then(async xhr => { + cy.verifyResponseCodes(xhr); + + const responseBody = await readResponseBlob(xhr.response.body); + + // Make sure data is sorted correctly + const firstRow = responseBody.data[0].values; + const secondRow = responseBody.data[1].values; + expect(firstRow[firstRow.length - 1].y).to.be.greaterThan( + secondRow[secondRow.length - 1].y, + ); + cy.verifySliceContainer('svg'); + }); + cy.get('.nv-area').should('have.length', 2); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.js deleted file mode 100644 index ede0659cd32be..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * 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 default () => - describe('Big Number', () => { - const BIG_NUMBER_FORM_DATA = { - datasource: '2__table', - viz_type: 'big_number', - slice_id: 42, - granularity_sqla: 'year', - time_grain_sqla: 'P1D', - time_range: '2000+:+2014-01-02', - metric: 'sum__SP_POP_TOTL', - adhoc_filters: [], - compare_lag: '10', - compare_suffix: 'over+10Y', - y_axis_format: '.3s', - show_trend_line: true, - start_y_axis_at_zero: true, - color_picker: { - r: 0, - g: 122, - b: 135, - a: 1, - }, - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - chartSelector: '.big_number', - }); - } - - beforeEach(() => { - cy.login(); - cy.server(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work', () => { - verify(BIG_NUMBER_FORM_DATA); - cy.get('.chart-container .header-line'); - cy.get('.chart-container .subheader-line'); - cy.get('.chart-container svg path.vx-linepath'); - }); - - it('should work without subheader', () => { - verify({ - ...BIG_NUMBER_FORM_DATA, - compare_lag: null, - }); - cy.get('.chart-container .header-line'); - cy.get('.chart-container .subheader-line').should('not.exist'); - cy.get('.chart-container svg path.vx-linepath'); - }); - - it('should not render trendline when hidden', () => { - verify({ - ...BIG_NUMBER_FORM_DATA, - show_trend_line: false, - }); - cy.get('.chart-container .header-line'); - cy.get('.chart-container .subheader-line'); - cy.get('.chart-container svg').should('not.exist'); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.test.js new file mode 100644 index 0000000000000..89ca8c4a567dc --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.test.js @@ -0,0 +1,82 @@ +/** + * 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. + */ +describe('Visualization > Big Number with Trendline', () => { + const BIG_NUMBER_FORM_DATA = { + datasource: '2__table', + viz_type: 'big_number', + slice_id: 42, + granularity_sqla: 'year', + time_grain_sqla: 'P1D', + time_range: '2000+:+2014-01-02', + metric: 'sum__SP_POP_TOTL', + adhoc_filters: [], + compare_lag: '10', + compare_suffix: 'over+10Y', + y_axis_format: '.3s', + show_trend_line: true, + start_y_axis_at_zero: true, + color_picker: { + r: 0, + g: 122, + b: 135, + a: 1, + }, + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + chartSelector: '.big_number', + }); + } + + beforeEach(() => { + cy.login(); + cy.server(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work', () => { + verify(BIG_NUMBER_FORM_DATA); + cy.get('.chart-container .header-line'); + cy.get('.chart-container .subheader-line'); + cy.get('.chart-container svg path.vx-linepath'); + }); + + it('should work without subheader', () => { + verify({ + ...BIG_NUMBER_FORM_DATA, + compare_lag: null, + }); + cy.get('.chart-container .header-line'); + cy.get('.chart-container .subheader-line').should('not.exist'); + cy.get('.chart-container svg path.vx-linepath'); + }); + + it('should not render trendline when hidden', () => { + verify({ + ...BIG_NUMBER_FORM_DATA, + show_trend_line: false, + }); + cy.get('.chart-container .header-line'); + cy.get('.chart-container .subheader-line'); + cy.get('.chart-container svg').should('not.exist'); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.js deleted file mode 100644 index fca86278d9fcd..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * 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 { FORM_DATA_DEFAULTS, NUM_METRIC } from './shared.helper'; -import readResponseBlob from '../../../utils/readResponseBlob'; - -// Big Number Total - -export default () => - describe('Big Number Total', () => { - const BIG_NUMBER_DEFAULTS = { - ...FORM_DATA_DEFAULTS, - viz_type: 'big_number_total', - }; - - beforeEach(() => { - cy.login(); - cy.server(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('Test big number chart with adhoc metric', () => { - const formData = { ...BIG_NUMBER_DEFAULTS, metric: NUM_METRIC }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: NUM_METRIC.label, - }); - }); - - it('Test big number chart with simple filter', () => { - const filters = [ - { - expressionType: 'SIMPLE', - subject: 'name', - operator: 'in', - comparator: ['Aaron', 'Amy', 'Andrea'], - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_4y6teao56zs_ebjsvwy48c', - }, - ]; - - const formData = { - ...BIG_NUMBER_DEFAULTS, - metric: 'count', - adhoc_filters: filters, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson' }); - }); - - it('Test big number chart ignores groupby', () => { - const formData = { - ...BIG_NUMBER_DEFAULTS, - metric: NUM_METRIC, - groupby: ['state'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.wait(['@getJson']).then(async xhr => { - cy.verifyResponseCodes(xhr); - cy.verifySliceContainer(); - - const responseBody = await readResponseBlob(xhr.response.body); - expect(responseBody.query).not.contains(formData.groupby[0]); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.test.js new file mode 100644 index 0000000000000..98aca2fc330c1 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.test.js @@ -0,0 +1,85 @@ +/** + * 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 { FORM_DATA_DEFAULTS, NUM_METRIC } from './shared.helper'; +import readResponseBlob from '../../../utils/readResponseBlob'; + +// Big Number Total + +describe('Visualization > Big Number Total', () => { + const BIG_NUMBER_DEFAULTS = { + ...FORM_DATA_DEFAULTS, + viz_type: 'big_number_total', + }; + + beforeEach(() => { + cy.login(); + cy.server(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('Test big number chart with adhoc metric', () => { + const formData = { ...BIG_NUMBER_DEFAULTS, metric: NUM_METRIC }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: NUM_METRIC.label, + }); + }); + + it('Test big number chart with simple filter', () => { + const filters = [ + { + expressionType: 'SIMPLE', + subject: 'name', + operator: 'in', + comparator: ['Aaron', 'Amy', 'Andrea'], + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_4y6teao56zs_ebjsvwy48c', + }, + ]; + + const formData = { + ...BIG_NUMBER_DEFAULTS, + metric: 'count', + adhoc_filters: filters, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson' }); + }); + + it('Test big number chart ignores groupby', () => { + const formData = { + ...BIG_NUMBER_DEFAULTS, + metric: NUM_METRIC, + groupby: ['state'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.wait(['@getJson']).then(async xhr => { + cy.verifyResponseCodes(xhr); + cy.verifySliceContainer(); + + const responseBody = await readResponseBlob(xhr.response.body); + expect(responseBody.query).not.contains(formData.groupby[0]); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/box_plot.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/box_plot.js deleted file mode 100644 index 5d4b8f37669b2..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/box_plot.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * 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 default () => - describe('Box Plot', () => { - const BOX_PLOT_FORM_DATA = { - datasource: '2__table', - viz_type: 'box_plot', - slice_id: 49, - granularity_sqla: 'year', - time_grain_sqla: 'P1D', - time_range: '1960-01-01+:+now', - metrics: ['sum__SP_POP_TOTL'], - adhoc_filters: [], - groupby: ['region'], - limit: '25', - color_scheme: 'bnbColors', - whisker_options: 'Min/max+(no+outliers)', - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work', () => { - verify(BOX_PLOT_FORM_DATA); - cy.get('.chart-container svg rect.nv-boxplot-box').should( - 'have.length', - 7, - ); - }); - - it('should work with filter', () => { - verify({ - ...BOX_PLOT_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'region', - operator: '==', - comparator: 'South Asia', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_8aqxcf5co1a_x7lm2d1fq0l', - }, - ], - }); - cy.get('.chart-container svg rect.nv-boxplot-box').should( - 'have.length', - 1, - ); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/box_plot.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/box_plot.test.js new file mode 100644 index 0000000000000..e58a7c06034e5 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/box_plot.test.js @@ -0,0 +1,68 @@ +/** + * 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. + */ +describe('Visualization > Box Plot', () => { + const BOX_PLOT_FORM_DATA = { + datasource: '2__table', + viz_type: 'box_plot', + slice_id: 49, + granularity_sqla: 'year', + time_grain_sqla: 'P1D', + time_range: '1960-01-01+:+now', + metrics: ['sum__SP_POP_TOTL'], + adhoc_filters: [], + groupby: ['region'], + limit: '25', + color_scheme: 'bnbColors', + whisker_options: 'Min/max+(no+outliers)', + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work', () => { + verify(BOX_PLOT_FORM_DATA); + cy.get('.chart-container svg rect.vx-boxplot-box').should('have.length', 7); + }); + + it('should work with filter', () => { + verify({ + ...BOX_PLOT_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'region', + operator: '==', + comparator: 'South Asia', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_8aqxcf5co1a_x7lm2d1fq0l', + }, + ], + }); + cy.get('.chart-container svg rect.vx-boxplot-box').should('have.length', 1); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/bubble.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/bubble.js deleted file mode 100644 index d9d735e45baf3..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/bubble.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * 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 default () => - describe('Bubble', () => { - const BUBBLE_FORM_DATA = { - datasource: '2__table', - viz_type: 'bubble', - slice_id: 46, - granularity_sqla: 'year', - time_grain_sqla: 'P1D', - time_range: '2011-01-01+:+2011-01-02', - series: 'region', - entity: 'country_name', - x: 'sum__SP_RUR_TOTL_ZS', - y: 'sum__SP_DYN_LE00_IN', - size: 'sum__SP_POP_TOTL', - max_bubble_size: '50', - limit: 0, - color_scheme: 'bnbColors', - show_legend: true, - x_axis_label: '', - left_margin: 'auto', - x_axis_format: '.3s', - x_ticks_layout: 'auto', - x_log_scale: false, - x_axis_showminmax: false, - y_axis_label: '', - bottom_margin: 'auto', - y_axis_format: '.3s', - y_log_scale: false, - y_axis_showminmax: false, - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work', () => { - verify(BUBBLE_FORM_DATA); - cy.get('.chart-container svg circle').should('have.length', 208); - }); - - it('should work with filter', () => { - verify({ - ...BUBBLE_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'region', - operator: '==', - comparator: 'South+Asia', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_b2tfg1rs8y_8kmrcyxvsqd', - }, - ], - }); - cy.get('.chart-container svg circle') - .should('have.length', 9) - .then(nodeList => { - // Check that all circles have same color. - const color = nodeList[0].getAttribute('fill'); - const circles = Array.prototype.slice.call(nodeList); - expect(circles.every(c => c.getAttribute('fill') === color)).to.equal( - true, - ); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/bubble.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/bubble.test.js new file mode 100644 index 0000000000000..1b449191726e7 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/bubble.test.js @@ -0,0 +1,95 @@ +/** + * 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. + */ +describe('Visualization > Bubble', () => { + const BUBBLE_FORM_DATA = { + datasource: '2__table', + viz_type: 'bubble', + slice_id: 46, + granularity_sqla: 'year', + time_grain_sqla: 'P1D', + time_range: '2011-01-01+:+2011-01-02', + series: 'region', + entity: 'country_name', + x: 'sum__SP_RUR_TOTL_ZS', + y: 'sum__SP_DYN_LE00_IN', + size: 'sum__SP_POP_TOTL', + max_bubble_size: '50', + limit: 0, + color_scheme: 'bnbColors', + show_legend: true, + x_axis_label: '', + left_margin: 'auto', + x_axis_format: '.3s', + x_ticks_layout: 'auto', + x_log_scale: false, + x_axis_showminmax: false, + y_axis_label: '', + bottom_margin: 'auto', + y_axis_format: '.3s', + y_log_scale: false, + y_axis_showminmax: false, + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work', () => { + verify(BUBBLE_FORM_DATA); + // number of circles = 214 rows + cy.get('.chart-container svg .nv-point-clips circle').should( + 'have.length', + 214, + ); + }); + + it('should work with filter', () => { + verify({ + ...BUBBLE_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'region', + operator: '==', + comparator: 'South+Asia', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_b2tfg1rs8y_8kmrcyxvsqd', + }, + ], + }); + cy.get('.chart-container svg .nv-point-clips circle') + .should('have.length', 8) + .then(nodeList => { + // Check that all circles have same color. + const color = nodeList[0].getAttribute('fill'); + const circles = Array.prototype.slice.call(nodeList); + expect(circles.every(c => c.getAttribute('fill') === color)).to.equal( + true, + ); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/compare.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/compare.js deleted file mode 100644 index c28ed9b399d2c..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/compare.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 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 default () => - describe('Compare', () => { - const COMPARE_FORM_DATA = { - datasource: '3__table', - viz_type: 'compare', - slice_id: 60, - granularity_sqla: 'ds', - time_grain_sqla: 'P1D', - time_range: '100 years ago : now', - metrics: ['count'], - adhoc_filters: [], - groupby: [], - order_desc: true, - contribution: false, - row_limit: 50000, - color_scheme: 'bnbColors', - x_axis_label: 'Frequency', - bottom_margin: 'auto', - x_ticks_layout: 'auto', - x_axis_format: 'smart_date', - x_axis_showminmax: false, - y_axis_label: 'Num', - left_margin: 'auto', - y_axis_showminmax: false, - y_log_scale: false, - y_axis_format: '.3s', - rolling_type: 'None', - comparison_type: 'values', - annotation_layers: [], - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work without groupby', () => { - verify(COMPARE_FORM_DATA); - cy.get('.chart-container .nvd3 path.nv-line').should('have.length', 1); - }); - - it('should with group by', () => { - verify({ - ...COMPARE_FORM_DATA, - groupby: ['gender'], - }); - cy.get('.chart-container .nvd3 path.nv-line').should('have.length', 2); - }); - - it('should work with filter', () => { - verify({ - ...COMPARE_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'gender', - operator: '==', - comparator: 'boy', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_tqx1en70hh_7nksse7nqic', - }, - ], - }); - cy.get('.chart-container .nvd3 path.nv-line').should('have.length', 1); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/compare.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/compare.test.js new file mode 100644 index 0000000000000..6b538f65a18e4 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/compare.test.js @@ -0,0 +1,90 @@ +/** + * 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. + */ +describe('Visualization > Compare', () => { + const COMPARE_FORM_DATA = { + datasource: '3__table', + viz_type: 'compare', + slice_id: 60, + granularity_sqla: 'ds', + time_grain_sqla: 'P1D', + time_range: '100 years ago : now', + metrics: ['count'], + adhoc_filters: [], + groupby: [], + order_desc: true, + contribution: false, + row_limit: 50000, + color_scheme: 'bnbColors', + x_axis_label: 'Frequency', + bottom_margin: 'auto', + x_ticks_layout: 'auto', + x_axis_format: 'smart_date', + x_axis_showminmax: false, + y_axis_label: 'Num', + left_margin: 'auto', + y_axis_showminmax: false, + y_log_scale: false, + y_axis_format: '.3s', + rolling_type: 'None', + comparison_type: 'values', + annotation_layers: [], + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work without groupby', () => { + verify(COMPARE_FORM_DATA); + cy.get('.chart-container .nvd3 path.nv-line').should('have.length', 1); + }); + + it('should with group by', () => { + verify({ + ...COMPARE_FORM_DATA, + groupby: ['gender'], + }); + cy.get('.chart-container .nvd3 path.nv-line').should('have.length', 2); + }); + + it('should work with filter', () => { + verify({ + ...COMPARE_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'gender', + operator: '==', + comparator: 'boy', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_tqx1en70hh_7nksse7nqic', + }, + ], + }); + cy.get('.chart-container .nvd3 path.nv-line').should('have.length', 1); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dist_bar.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dist_bar.js deleted file mode 100644 index 7b3a8f0440a67..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dist_bar.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 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 { FORM_DATA_DEFAULTS, NUM_METRIC } from './shared.helper'; - -// Dist bar - -export default () => - describe('Distribution bar chart', () => { - const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'dist_bar' }; - - beforeEach(() => { - cy.login(); - cy.server(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('Test dist bar with adhoc metric', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: NUM_METRIC, - groupby: ['state'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: NUM_METRIC.label, - chartSelector: 'svg', - }); - }); - - it('Test dist bar with series', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: NUM_METRIC, - groupby: ['state'], - columns: ['gender'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test dist bar with row limit', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: NUM_METRIC, - groupby: ['state'], - row_limit: 10, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test dist bar with contribution', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: NUM_METRIC, - groupby: ['state'], - columns: ['gender'], - contribution: true, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dist_bar.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dist_bar.test.js new file mode 100644 index 0000000000000..b2a711445131d --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dist_bar.test.js @@ -0,0 +1,81 @@ +/** + * 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 { FORM_DATA_DEFAULTS, NUM_METRIC } from './shared.helper'; + +describe('Visualization > Distribution bar chart', () => { + const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'dist_bar' }; + + beforeEach(() => { + cy.login(); + cy.server(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work with adhoc metric', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: NUM_METRIC, + groupby: ['state'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: NUM_METRIC.label, + chartSelector: 'svg', + }); + }); + + it('should work with series', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: NUM_METRIC, + groupby: ['state'], + columns: ['gender'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with row limit', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: NUM_METRIC, + groupby: ['state'], + row_limit: 10, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with contribution', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: NUM_METRIC, + groupby: ['state'], + columns: ['gender'], + contribution: true, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dual_line.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dual_line.js deleted file mode 100644 index da302d19eafa2..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dual_line.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * 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 default () => - describe('Dual Line', () => { - const DUAL_LINE_FORM_DATA = { - datasource: '3__table', - viz_type: 'dual_line', - slice_id: 58, - granularity_sqla: 'ds', - time_grain_sqla: 'P1D', - time_range: '100+years+ago+:+now', - color_scheme: 'bnbColors', - x_axis_format: 'smart_date', - metric: 'avg__num', - y_axis_format: '.3s', - metric_2: 'sum__num', - y_axis_2_format: '.3s', - adhoc_filters: [], - annotation_layers: [], - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work', () => { - verify(DUAL_LINE_FORM_DATA); - cy.get('.chart-container svg path.nv-line').should('have.length', 2); - }); - - it('should work with filter', () => { - verify({ - ...DUAL_LINE_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'gender', - operator: '==', - comparator: 'girl', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_1ep6q50g8vk_48jj6qxdems', - }, - ], - }); - cy.get('.chart-container svg path.nv-line').should('have.length', 2); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dual_line.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dual_line.test.js new file mode 100644 index 0000000000000..bfe8660440fe7 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/dual_line.test.js @@ -0,0 +1,70 @@ +/** + * 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. + */ +describe('Visualization > Dual Line', () => { + const DUAL_LINE_FORM_DATA = { + datasource: '3__table', + viz_type: 'dual_line', + slice_id: 58, + granularity_sqla: 'ds', + time_grain_sqla: 'P1D', + time_range: '100+years+ago+:+now', + color_scheme: 'bnbColors', + x_axis_format: 'smart_date', + metric: 'sum__num', + y_axis_format: '.3s', + metric_2: 'count', + y_axis_2_format: '.3s', + adhoc_filters: [], + annotation_layers: [], + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work', () => { + verify(DUAL_LINE_FORM_DATA); + cy.get('.chart-container svg path.nv-line').should('have.length', 2); + }); + + it('should work with filter', () => { + verify({ + ...DUAL_LINE_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'gender', + operator: '==', + comparator: 'girl', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_1ep6q50g8vk_48jj6qxdems', + }, + ], + }); + cy.get('.chart-container svg path.nv-line').should('have.length', 2); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/filter_box.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/filter_box.js deleted file mode 100644 index f62937de8c578..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/filter_box.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 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 { FORM_DATA_DEFAULTS } from './shared.helper'; - -export default () => - describe('FilterBox', () => { - const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'filter_box' }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work with default date filter', () => { - verify(VIZ_DEFAULTS); - // Filter box should default to having a date filter with no filter selected - cy.get('div.filter_box').within(() => { - cy.get('span').contains('No filter'); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/histogram.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/histogram.js deleted file mode 100644 index c732691a2fc3c..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/histogram.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * 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 default () => - describe('Histogram', () => { - const HISTOGRAM_FORM_DATA = { - datasource: '3__table', - viz_type: 'histogram', - slice_id: 60, - granularity_sqla: 'ds', - time_grain_sqla: 'P1D', - time_range: '100 years ago : now', - all_columns_x: ['num'], - adhoc_filters: [], - row_limit: 50000, - groupby: [], - color_scheme: 'bnbColors', - link_length: 5, - x_axis_label: 'Frequency', - y_axis_label: 'Num', - global_opacity: 1, - normalized: false, - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work without groupby', () => { - verify(HISTOGRAM_FORM_DATA); - cy.get('.chart-container svg .vx-bar').should('have.length', 6); - }); - - it('should with group by', () => { - verify({ - ...HISTOGRAM_FORM_DATA, - groupby: ['gender'], - }); - cy.get('.chart-container svg .vx-bar').should('have.length', 12); - }); - - it('should work with filter', () => { - verify({ - ...HISTOGRAM_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'gender', - operator: '==', - comparator: 'boy', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_tqx1en70hh_7nksse7nqic', - }, - ], - }); - cy.get('.chart-container svg .vx-bar').should('have.length', 5); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/histogram.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/histogram.test.js new file mode 100644 index 0000000000000..78ec06e7c50c5 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/histogram.test.js @@ -0,0 +1,88 @@ +/** + * 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. + */ +describe('Visualization > Histogram', () => { + const HISTOGRAM_FORM_DATA = { + datasource: '3__table', + viz_type: 'histogram', + slice_id: 60, + granularity_sqla: 'ds', + time_grain_sqla: 'P1D', + time_range: '100 years ago : now', + all_columns_x: ['num'], + adhoc_filters: [], + row_limit: 50000, + groupby: [], + color_scheme: 'bnbColors', + link_length: 5, // number of bins + x_axis_label: 'Frequency', + y_axis_label: 'Num', + global_opacity: 1, + normalized: false, + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work without groupby', () => { + verify(HISTOGRAM_FORM_DATA); + cy.get('.chart-container svg .vx-bar').should( + 'have.length', + HISTOGRAM_FORM_DATA.link_length, + ); + }); + + it('should work with group by', () => { + verify({ + ...HISTOGRAM_FORM_DATA, + groupby: ['gender'], + }); + cy.get('.chart-container svg .vx-bar').should( + 'have.length', + HISTOGRAM_FORM_DATA.link_length * 2, + ); + }); + + it('should work with filter and update num bins', () => { + const numBins = 2; + verify({ + ...HISTOGRAM_FORM_DATA, + link_length: numBins, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'state', + operator: '==', + comparator: 'CA', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_tqx1en70hh_7nksse7nqic', + }, + ], + }); + cy.get('.chart-container svg .vx-bar').should('have.length', numBins); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/index.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/index.test.js deleted file mode 100644 index cd1558777f0c3..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/index.test.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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 AreaTest from './area'; -import BigNumberTest from './big_number'; -import BigNumberTotalTest from './big_number_total'; -import BubbleTest from './bubble'; -import CompareTest from './compare'; -import DistBarTest from './dist_bar'; -import DualLineTest from './dual_line'; -import FilterBox from './filter_box'; -import HistogramTest from './histogram'; -import LineTest from './line'; -import PieTest from './pie'; -import PivotTableTest from './pivot_table'; -import SankeyTest from './sankey'; -import SunburstTest from './sunburst'; -import TableTest from './table'; -import TimeTableTest from './time_table'; -import TreemapTest from './treemap'; -import WorldMapTest from './world_map'; - -describe('All Visualizations', () => { - AreaTest(); - BigNumberTest(); - BigNumberTotalTest(); - BubbleTest(); - CompareTest(); - DistBarTest(); - DualLineTest(); - FilterBox(); - HistogramTest(); - LineTest(); - PieTest(); - PivotTableTest(); - SankeyTest(); - SunburstTest(); - TableTest(); - TimeTableTest(); - TreemapTest(); - WorldMapTest(); -}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.js deleted file mode 100644 index 1292072d39516..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.js +++ /dev/null @@ -1,258 +0,0 @@ -/** - * 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 { FORM_DATA_DEFAULTS, NUM_METRIC, SIMPLE_FILTER } from './shared.helper'; - -export default () => - describe('Line', () => { - const LINE_CHART_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'line' }; - - beforeEach(() => { - cy.login(); - cy.server(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('Test line chart with adhoc metric', () => { - const formData = { ...LINE_CHART_DEFAULTS, metrics: [NUM_METRIC] }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test line chart with groupby', () => { - const metrics = ['count']; - const groupby = ['gender']; - - const formData = { ...LINE_CHART_DEFAULTS, metrics, groupby }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test line chart with simple filter', () => { - const metrics = ['count']; - const filters = [SIMPLE_FILTER]; - - const formData = { - ...LINE_CHART_DEFAULTS, - metrics, - adhoc_filters: filters, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test line chart with series limit sort asc', () => { - const formData = { - ...LINE_CHART_DEFAULTS, - metrics: [NUM_METRIC], - limit: 10, - groupby: ['name'], - timeseries_limit_metric: NUM_METRIC, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test line chart with series limit sort desc', () => { - const formData = { - ...LINE_CHART_DEFAULTS, - metrics: [NUM_METRIC], - limit: 10, - groupby: ['name'], - timeseries_limit_metric: NUM_METRIC, - order_desc: true, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test line chart with rolling avg', () => { - const metrics = [NUM_METRIC]; - - const formData = { - ...LINE_CHART_DEFAULTS, - metrics, - rolling_type: 'mean', - rolling_periods: 10, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test line chart with time shift 1 year', () => { - const metrics = [NUM_METRIC]; - - const formData = { - ...LINE_CHART_DEFAULTS, - metrics, - time_compare: ['1+year'], - comparison_type: 'values', - groupby: ['gender'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - - // Offset color should match original line color - cy.get('.nv-legend-text') - .contains('boy') - .siblings() - .first() - .should('have.attr', 'style') - .then(style => { - cy.get('.nv-legend-text') - .contains('boy, 1 year offset') - .siblings() - .first() - .should('have.attr', 'style') - .and('eq', style); - }); - - cy.get('.nv-legend-text') - .contains('girl') - .siblings() - .first() - .should('have.attr', 'style') - .then(style => { - cy.get('.nv-legend-text') - .contains('girl, 1 year offset') - .siblings() - .first() - .should('have.attr', 'style') - .and('eq', style); - }); - }); - - it('Test line chart with time shift yoy', () => { - const metrics = [NUM_METRIC]; - - const formData = { - ...LINE_CHART_DEFAULTS, - metrics, - time_compare: ['1+year'], - comparison_type: 'ratio', - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test line chart with time shift percentage change', () => { - const metrics = [NUM_METRIC]; - - const formData = { - ...LINE_CHART_DEFAULTS, - metrics, - time_compare: ['1+year'], - comparison_type: 'percentage', - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - }); - - it('Test verbose name shows up in legend', () => { - const formData = { - ...LINE_CHART_DEFAULTS, - metrics: ['count'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - cy.get('text.nv-legend-text').contains('COUNT(*)'); - }); - - it('Test hidden annotation', () => { - const formData = { - ...LINE_CHART_DEFAULTS, - metrics: ['count'], - annotation_layers: [ - { - name: 'Goal+line', - annotationType: 'FORMULA', - sourceType: '', - value: 'y=140000', - overrides: { time_range: null }, - show: false, - titleColumn: '', - descriptionColumns: [], - timeColumn: '', - intervalEndColumn: '', - color: null, - opacity: '', - style: 'solid', - width: 1, - showMarkers: false, - hideLine: false, - }, - ], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - cy.get('.slice_container').within(() => { - // Goal line annotation doesn't show up in legend - cy.get('.nv-legend-text').should('have.length', 1); - }); - }); - - it('Test event annotation time override', () => { - cy.request('/chart/api/read?_flt_3_slice_name=Daily+Totals').then( - response => { - const value = response.body.pks[0]; - const formData = { - ...LINE_CHART_DEFAULTS, - metrics: ['count'], - annotation_layers: [ - { - name: 'Yearly date', - annotationType: 'EVENT', - sourceType: 'table', - value, - overrides: { time_range: null }, - show: true, - titleColumn: 'ds', - descriptionColumns: ['ds'], - timeColumn: 'ds', - color: null, - opacity: '', - style: 'solid', - width: 1, - showMarkers: false, - hideLine: false, - }, - ], - }; - cy.visitChartByParams(JSON.stringify(formData)); - }, - ); - - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - cy.get('.slice_container').within(() => { - cy.get('.nv-event-annotation-layer-0') - .children() - .should('have.length', 44); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.js new file mode 100644 index 0000000000000..5314a016d5733 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.js @@ -0,0 +1,257 @@ +/** + * 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 { FORM_DATA_DEFAULTS, NUM_METRIC, SIMPLE_FILTER } from './shared.helper'; + +describe('Visualization > Line', () => { + const LINE_CHART_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'line' }; + + beforeEach(() => { + cy.login(); + cy.server(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work with adhoc metric', () => { + const formData = { ...LINE_CHART_DEFAULTS, metrics: [NUM_METRIC] }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with groupby', () => { + const metrics = ['count']; + const groupby = ['gender']; + + const formData = { ...LINE_CHART_DEFAULTS, metrics, groupby }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with simple filter', () => { + const metrics = ['count']; + const filters = [SIMPLE_FILTER]; + + const formData = { + ...LINE_CHART_DEFAULTS, + metrics, + adhoc_filters: filters, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with series limit sort asc', () => { + const formData = { + ...LINE_CHART_DEFAULTS, + metrics: [NUM_METRIC], + limit: 10, + groupby: ['name'], + timeseries_limit_metric: NUM_METRIC, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with series limit sort desc', () => { + const formData = { + ...LINE_CHART_DEFAULTS, + metrics: [NUM_METRIC], + limit: 10, + groupby: ['name'], + timeseries_limit_metric: NUM_METRIC, + order_desc: true, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with rolling avg', () => { + const metrics = [NUM_METRIC]; + + const formData = { + ...LINE_CHART_DEFAULTS, + metrics, + rolling_type: 'mean', + rolling_periods: 10, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with time shift 1 year', () => { + const metrics = [NUM_METRIC]; + + const formData = { + ...LINE_CHART_DEFAULTS, + metrics, + time_compare: ['1+year'], + comparison_type: 'values', + groupby: ['gender'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + + // Offset color should match original line color + cy.get('.nv-legend-text') + .contains('boy') + .siblings() + .first() + .should('have.attr', 'style') + .then(style => { + cy.get('.nv-legend-text') + .contains('boy, 1 year offset') + .siblings() + .first() + .should('have.attr', 'style') + .and('eq', style); + }); + + cy.get('.nv-legend-text') + .contains('girl') + .siblings() + .first() + .should('have.attr', 'style') + .then(style => { + cy.get('.nv-legend-text') + .contains('girl, 1 year offset') + .siblings() + .first() + .should('have.attr', 'style') + .and('eq', style); + }); + }); + + it('should work with time shift yoy', () => { + const metrics = [NUM_METRIC]; + + const formData = { + ...LINE_CHART_DEFAULTS, + metrics, + time_compare: ['1+year'], + comparison_type: 'ratio', + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('should work with time shift percentage change', () => { + const metrics = [NUM_METRIC]; + + const formData = { + ...LINE_CHART_DEFAULTS, + metrics, + time_compare: ['1+year'], + comparison_type: 'percentage', + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + }); + + it('Test verbose name shows up in legend', () => { + const formData = { + ...LINE_CHART_DEFAULTS, + metrics: ['count'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + cy.get('text.nv-legend-text').contains('COUNT(*)'); + }); + + it('Test hidden annotation', () => { + const formData = { + ...LINE_CHART_DEFAULTS, + metrics: ['count'], + annotation_layers: [ + { + name: 'Goal+line', + annotationType: 'FORMULA', + sourceType: '', + value: 'y=140000', + overrides: { time_range: null }, + show: false, + titleColumn: '', + descriptionColumns: [], + timeColumn: '', + intervalEndColumn: '', + color: null, + opacity: '', + style: 'solid', + width: 1, + showMarkers: false, + hideLine: false, + }, + ], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + cy.get('.slice_container').within(() => { + // Goal line annotation doesn't show up in legend + cy.get('.nv-legend-text').should('have.length', 1); + }); + }); + + it('Test event annotation time override', () => { + cy.request('/chart/api/read?_flt_3_slice_name=Daily+Totals').then( + response => { + const value = response.body.pks[0]; + const formData = { + ...LINE_CHART_DEFAULTS, + metrics: ['count'], + annotation_layers: [ + { + name: 'Yearly date', + annotationType: 'EVENT', + sourceType: 'table', + value, + overrides: { time_range: null }, + show: true, + titleColumn: 'ds', + descriptionColumns: ['ds'], + timeColumn: 'ds', + color: null, + opacity: '', + style: 'solid', + width: 1, + showMarkers: false, + hideLine: false, + }, + ], + }; + cy.visitChartByParams(JSON.stringify(formData)); + }, + ); + + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + cy.get('.slice_container').within(() => { + cy.get('.nv-event-annotation-layer-0') + .children() + .should('have.length', 44); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pie.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pie.js deleted file mode 100644 index 39ae873f6b552..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pie.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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 default () => - describe('Pie', () => { - const PIE_FORM_DATA = { - datasource: '3__table', - viz_type: 'pie', - slice_id: 55, - granularity_sqla: 'ds', - time_grain_sqla: 'P1D', - time_range: '100 years ago : now', - metric: 'sum__num', - adhoc_filters: [], - groupby: ['gender'], - row_limit: 50000, - pie_label_type: 'key', - donut: false, - show_legend: true, - show_labels: true, - labels_outside: true, - color_scheme: 'bnbColors', - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work with ad-hoc metric', () => { - verify(PIE_FORM_DATA); - cy.get('.chart-container .nv-pie .nv-slice path').should( - 'have.length', - 2, - ); - }); - - it('should work with simple filter', () => { - verify({ - ...PIE_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'gender', - operator: '==', - comparator: 'boy', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_tqx1en70hh_7nksse7nqic', - }, - ], - }); - cy.get('.chart-container .nv-pie .nv-slice path').should( - 'have.length', - 1, - ); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pie.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pie.test.js new file mode 100644 index 0000000000000..6c2dc68699412 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pie.test.js @@ -0,0 +1,72 @@ +/** + * 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. + */ +describe('Visualization > Pie', () => { + const PIE_FORM_DATA = { + datasource: '3__table', + viz_type: 'pie', + slice_id: 55, + granularity_sqla: 'ds', + time_grain_sqla: 'P1D', + time_range: '100 years ago : now', + metric: 'sum__num', + adhoc_filters: [], + groupby: ['gender'], + row_limit: 50000, + pie_label_type: 'key', + donut: false, + show_legend: true, + show_labels: true, + labels_outside: true, + color_scheme: 'bnbColors', + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work with ad-hoc metric', () => { + verify(PIE_FORM_DATA); + cy.get('.chart-container .nv-pie .nv-slice path').should('have.length', 2); + }); + + it('should work with simple filter', () => { + verify({ + ...PIE_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'gender', + operator: '==', + comparator: 'boy', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_tqx1en70hh_7nksse7nqic', + }, + ], + }); + cy.get('.chart-container .nv-pie .nv-slice path').should('have.length', 1); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pivot_table.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pivot_table.js deleted file mode 100644 index 7157d8ab147cc..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pivot_table.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * 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 default () => - describe('Pivot Table', () => { - const PIVOT_TABLE_FORM_DATA = { - datasource: '3__table', - viz_type: 'pivot_table', - slice_id: 61, - granularity_sqla: 'ds', - time_grain_sqla: 'P1D', - time_range: '100+years+ago+:+now', - metrics: ['sum__num'], - adhoc_filters: [], - groupby: ['name'], - columns: ['state'], - row_limit: 50000, - pandas_aggfunc: 'sum', - pivot_margins: true, - number_format: '.3s', - combine_metric: false, - }; - - const TEST_METRIC = { - expressionType: 'SIMPLE', - column: { - id: 338, - column_name: 'sum_boys', - expression: '', - filterable: false, - groupby: false, - is_dttm: false, - type: 'BIGINT', - optionName: '_col_sum_boys', - }, - aggregate: 'SUM', - hasCustomLabel: false, - label: 'SUM(sum_boys)', - optionName: 'metric_gvpdjt0v2qf_6hkf56o012', - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work with single groupby', () => { - verify(PIVOT_TABLE_FORM_DATA); - cy.get('.chart-container tr th').then(ths => { - expect(ths.find(th => th.innerText.trim() === 'name')).to.not.equal( - undefined, - ); - }); - }); - - it('should work with more than one groupby', () => { - verify({ - ...PIVOT_TABLE_FORM_DATA, - groupby: ['name', 'gender'], - }); - cy.get('.chart-container tr th').then(ths => { - expect(ths.find(th => th.innerText.trim() === 'name')).to.not.equal( - undefined, - ); - expect(ths.find(th => th.innerText.trim() === 'gender')).to.not.equal( - undefined, - ); - }); - }); - - it('should work with multiple metrics', () => { - verify({ - ...PIVOT_TABLE_FORM_DATA, - metrics: ['sum__num', TEST_METRIC], - }); - cy.get('.chart-container tr th').then(ths => { - expect(ths.find(th => th.innerText.trim() === 'sum__num')).to.not.equal( - undefined, - ); - expect( - ths.find(th => th.innerText.trim() === 'SUM(sum_boys)'), - ).to.not.equal(undefined); - }); - }); - - it('should work with multiple groupby and multiple metrics', () => { - verify({ - ...PIVOT_TABLE_FORM_DATA, - groupby: ['name', 'gender'], - metrics: ['sum__num', TEST_METRIC], - }); - cy.get('.chart-container tr th').then(ths => { - expect(ths.find(th => th.innerText.trim() === 'name')).to.not.equal( - undefined, - ); - expect(ths.find(th => th.innerText.trim() === 'gender')).to.not.equal( - undefined, - ); - expect(ths.find(th => th.innerText.trim() === 'sum__num')).to.not.equal( - undefined, - ); - expect( - ths.find(th => th.innerText.trim() === 'SUM(sum_boys)'), - ).to.not.equal(undefined); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pivot_table.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pivot_table.test.js new file mode 100644 index 0000000000000..32e9923d6bac1 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/pivot_table.test.js @@ -0,0 +1,107 @@ +/** + * 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. + */ +describe('Visualization > Pivot Table', () => { + const PIVOT_TABLE_FORM_DATA = { + datasource: '3__table', + viz_type: 'pivot_table', + slice_id: 61, + granularity_sqla: 'ds', + time_grain_sqla: 'P1D', + time_range: '100+years+ago+:+now', + metrics: ['sum__num'], + adhoc_filters: [], + groupby: ['name'], + columns: ['state'], + row_limit: 50000, + pandas_aggfunc: 'sum', + pivot_margins: true, + number_format: '.3s', + combine_metric: false, + }; + + const TEST_METRIC = { + expressionType: 'SIMPLE', + column: { + id: 338, + column_name: 'sum_boys', + expression: '', + filterable: false, + groupby: false, + is_dttm: false, + type: 'BIGINT', + optionName: '_col_sum_boys', + }, + aggregate: 'SUM', + hasCustomLabel: false, + label: 'SUM(sum_boys)', + optionName: 'metric_gvpdjt0v2qf_6hkf56o012', + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work with single groupby', () => { + verify(PIVOT_TABLE_FORM_DATA); + cy.get('.chart-container tr:eq(0) th:eq(1)').contains('sum__num'); + cy.get('.chart-container tr:eq(1) th:eq(0)').contains('state'); + cy.get('.chart-container tr:eq(2) th:eq(0)').contains('name'); + }); + + it('should work with more than one groupby', () => { + verify({ + ...PIVOT_TABLE_FORM_DATA, + groupby: ['name', 'gender'], + }); + cy.get('.chart-container tr:eq(0) th:eq(2)').contains('sum__num'); + cy.get('.chart-container tr:eq(1) th:eq(1)').contains('state'); + cy.get('.chart-container tr:eq(2) th:eq(0)').contains('name'); + cy.get('.chart-container tr:eq(2) th:eq(1)').contains('gender'); + }); + + it('should work with multiple metrics', () => { + verify({ + ...PIVOT_TABLE_FORM_DATA, + metrics: ['sum__num', TEST_METRIC], + }); + cy.get('.chart-container tr:eq(0) th:eq(1)').contains('sum__num'); + cy.get('.chart-container tr:eq(0) th:eq(2)').contains('SUM(sum_boys)'); + cy.get('.chart-container tr:eq(1) th:eq(0)').contains('state'); + cy.get('.chart-container tr:eq(2) th:eq(0)').contains('name'); + }); + + it('should work with multiple groupby and multiple metrics', () => { + verify({ + ...PIVOT_TABLE_FORM_DATA, + groupby: ['name', 'gender'], + metrics: ['sum__num', TEST_METRIC], + }); + cy.get('.chart-container tr:eq(0) th:eq(2)').contains('sum__num'); + cy.get('.chart-container tr:eq(0) th:eq(3)').contains('SUM(sum_boys)'); + cy.get('.chart-container tr:eq(2) th:eq(0)').contains('name'); + cy.get('.chart-container tr:eq(2) th:eq(1)').contains('gender'); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sankey.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sankey.js deleted file mode 100644 index 0d1de942224a7..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sankey.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * 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 default () => - describe('Sankey', () => { - const SANKEY_FORM_DATA = { - datasource: '1__table', - viz_type: 'sankey', - slice_id: 1, - url_params: {}, - granularity_sqla: null, - time_grain_sqla: 'P1D', - time_range: 'Last+week', - groupby: ['source', 'target'], - metric: 'sum__value', - adhoc_filters: [], - row_limit: '5000', - color_scheme: 'bnbColors', - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work', () => { - verify(SANKEY_FORM_DATA); - cy.get('.chart-container svg g.node rect').should('have.length', 41); - }); - - it('should work with filter', () => { - verify({ - ...SANKEY_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SQL', - sqlExpression: 'SUM(value)+>+0', - clause: 'HAVING', - subject: null, - operator: null, - comparator: null, - filterOptionName: 'filter_jbdwe0hayaj_h9jfer8fy58', - }, - { - expressionType: 'SIMPLE', - subject: 'source', - operator: '==', - comparator: 'Energy', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_8e0otka9uif_vmqri4gmbqc', - }, - ], - }); - cy.get('.chart-container svg g.node rect').should('have.length', 6); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sankey.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sankey.test.js new file mode 100644 index 0000000000000..dc113df2e5b9a --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sankey.test.js @@ -0,0 +1,77 @@ +/** + * 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. + */ +describe('Visualization > Sankey', () => { + const SANKEY_FORM_DATA = { + datasource: '1__table', + viz_type: 'sankey', + slice_id: 1, + url_params: {}, + granularity_sqla: null, + time_grain_sqla: 'P1D', + time_range: 'Last+week', + groupby: ['source', 'target'], + metric: 'sum__value', + adhoc_filters: [], + row_limit: '5000', + color_scheme: 'bnbColors', + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work', () => { + verify(SANKEY_FORM_DATA); + cy.get('.chart-container svg g.node rect').should('have.length', 41); + }); + + it('should work with filter', () => { + verify({ + ...SANKEY_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SQL', + sqlExpression: 'SUM(value)+>+0', + clause: 'HAVING', + subject: null, + operator: null, + comparator: null, + filterOptionName: 'filter_jbdwe0hayaj_h9jfer8fy58', + }, + { + expressionType: 'SIMPLE', + subject: 'source', + operator: '==', + comparator: 'Energy', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_8e0otka9uif_vmqri4gmbqc', + }, + ], + }); + cy.get('.chart-container svg g.node rect').should('have.length', 6); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sunburst.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sunburst.js deleted file mode 100644 index adaaaf82b8a57..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sunburst.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * 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 default () => - describe('Sunburst', () => { - const SUNBURST_FORM_DATA = { - datasource: '2__table', - viz_type: 'sunburst', - slice_id: 47, - granularity_sqla: 'year', - time_grain_sqla: 'P1D', - time_range: '2011-01-01+:+2011-01-01', - groupby: ['region'], - metric: 'sum__SP_POP_TOTL', - adhoc_filters: [], - row_limit: 50000, - color_scheme: 'bnbColors', - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work without secondary metric', () => { - verify(SUNBURST_FORM_DATA); - // There should be 7 visible arcs + 1 hidden - cy.get('.chart-container svg g#arcs path').should('have.length', 8); - }); - - it('should work with secondary metric', () => { - verify({ - ...SUNBURST_FORM_DATA, - secondary_metric: 'sum__SP_RUR_TOTL', - }); - cy.get('.chart-container svg g#arcs path').should('have.length', 8); - }); - - it('should work with multiple groupbys', () => { - verify({ - ...SUNBURST_FORM_DATA, - groupby: ['region', 'country_name'], - }); - cy.get('.chart-container svg g#arcs path').should('have.length', 118); - }); - - it('should work with filter', () => { - verify({ - ...SUNBURST_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'region', - operator: 'in', - comparator: ['South Asia', 'North America'], - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_txje2ikiv6_wxmn0qwd1xo', - }, - ], - }); - cy.get('.chart-container svg g#arcs path').should('have.length', 3); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sunburst.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sunburst.test.js new file mode 100644 index 0000000000000..d3b39e8437757 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/sunburst.test.js @@ -0,0 +1,84 @@ +/** + * 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. + */ +describe('Visualization > Sunburst', () => { + const SUNBURST_FORM_DATA = { + datasource: '2__table', + viz_type: 'sunburst', + slice_id: 47, + granularity_sqla: 'year', + time_grain_sqla: 'P1D', + time_range: 'No filter', + groupby: ['region'], + metric: 'sum__SP_POP_TOTL', + adhoc_filters: [], + row_limit: 50000, + color_scheme: 'bnbColors', + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work without secondary metric', () => { + verify(SUNBURST_FORM_DATA); + // There should be 7 visible arcs + 1 hidden + cy.get('.chart-container svg g#arcs path').should('have.length', 8); + }); + + it('should work with secondary metric', () => { + verify({ + ...SUNBURST_FORM_DATA, + secondary_metric: 'sum__SP_RUR_TOTL', + }); + cy.get('.chart-container svg g#arcs path').should('have.length', 8); + }); + + it('should work with multiple groupbys', () => { + verify({ + ...SUNBURST_FORM_DATA, + groupby: ['region', 'country_name'], + }); + cy.get('.chart-container svg g#arcs path').should('have.length', 117); + }); + + it('should work with filter', () => { + verify({ + ...SUNBURST_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'region', + operator: 'in', + comparator: ['South Asia', 'North America'], + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_txje2ikiv6_wxmn0qwd1xo', + }, + ], + }); + cy.get('.chart-container svg g#arcs path').should('have.length', 3); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/table.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/table.js deleted file mode 100644 index c5e5b041970f7..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/table.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * 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 { FORM_DATA_DEFAULTS, NUM_METRIC, SIMPLE_FILTER } from './shared.helper'; -import readResponseBlob from '../../../utils/readResponseBlob'; - -// Table - -export default () => - describe('Table chart', () => { - const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'table' }; - - beforeEach(() => { - cy.login(); - cy.server(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('Test table with adhoc metric', () => { - const formData = { ...VIZ_DEFAULTS, metrics: NUM_METRIC }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: NUM_METRIC.label, - chartSelector: 'table', - }); - }); - - it('Test table with groupby', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: NUM_METRIC, - groupby: ['name'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: formData.groupby[0], - chartSelector: 'table', - }); - }); - - it('Test table with percent metrics and groupby', () => { - const formData = { - ...VIZ_DEFAULTS, - percent_metrics: NUM_METRIC, - metrics: [], - groupby: ['name'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); - }); - - it('Test table with groupby order desc', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: NUM_METRIC, - groupby: ['name'], - order_desc: true, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); - }); - - it('Test table with groupby and limit', () => { - const limit = 10; - - const formData = { - ...VIZ_DEFAULTS, - metrics: NUM_METRIC, - groupby: ['name'], - row_limit: limit, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - - cy.wait('@getJson').then(async xhr => { - cy.verifyResponseCodes(xhr); - cy.verifySliceContainer('table'); - const responseBody = await readResponseBlob(xhr.response.body); - expect(responseBody.data.records.length).to.eq(limit); - }); - cy.get('span.label-danger').contains('10 rows'); - }); - - it('Test table with columns and row limit', () => { - const formData = { - ...VIZ_DEFAULTS, - all_columns: ['name'], - metrics: [], - row_limit: 10, - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); - }); - - it('Test table with columns, ordering, and row limit', () => { - const limit = 10; - - const formData = { - ...VIZ_DEFAULTS, - all_columns: ['name', 'state', 'ds', 'num'], - metrics: [], - row_limit: limit, - order_by_cols: ['["num",+false]'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.wait('@getJson').then(async xhr => { - cy.verifyResponseCodes(xhr); - cy.verifySliceContainer('table'); - const responseBody = await readResponseBlob(xhr.response.body); - const { records } = responseBody.data; - expect(records[0].num).greaterThan(records[records.length - 1].num); - }); - }); - - it('Test table with simple filter', () => { - const metrics = ['count']; - const filters = [SIMPLE_FILTER]; - - const formData = { ...VIZ_DEFAULTS, metrics, adhoc_filters: filters }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); - }); - - it('Tests table number formatting with % in metric name', () => { - const PERCENT_METRIC = { - expressionType: 'SQL', - sqlExpression: 'CAST(SUM(sum_girls)+AS+FLOAT)/SUM(num)', - column: null, - aggregate: null, - hasCustomLabel: true, - label: '%+Girls', - optionName: 'metric_6qwzgc8bh2v_zox7hil1mzs', - }; - const formData = { - ...VIZ_DEFAULTS, - metrics: PERCENT_METRIC, - groupby: ['state'], - }; - - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: formData.groupby[0], - chartSelector: 'table', - }); - cy.get('td').contains(/\d*%/); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/table.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/table.test.js new file mode 100644 index 0000000000000..d9c92d3d58df1 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/table.test.js @@ -0,0 +1,170 @@ +/** + * 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 { FORM_DATA_DEFAULTS, NUM_METRIC, SIMPLE_FILTER } from './shared.helper'; +import readResponseBlob from '../../../utils/readResponseBlob'; + +// Table +describe('Visualization > Table', () => { + const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'table' }; + + beforeEach(() => { + cy.login(); + cy.server(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('Test table with adhoc metric', () => { + const formData = { ...VIZ_DEFAULTS, metrics: NUM_METRIC }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: NUM_METRIC.label, + chartSelector: 'table', + }); + }); + + it('Test table with groupby', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: NUM_METRIC, + groupby: ['name'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: formData.groupby[0], + chartSelector: 'table', + }); + }); + + it('Test table with percent metrics and groupby', () => { + const formData = { + ...VIZ_DEFAULTS, + percent_metrics: NUM_METRIC, + metrics: [], + groupby: ['name'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); + }); + + it('Test table with groupby order desc', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: NUM_METRIC, + groupby: ['name'], + order_desc: true, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); + }); + + it('Test table with groupby and limit', () => { + const limit = 10; + + const formData = { + ...VIZ_DEFAULTS, + metrics: NUM_METRIC, + groupby: ['name'], + row_limit: limit, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + + cy.wait('@getJson').then(async xhr => { + cy.verifyResponseCodes(xhr); + cy.verifySliceContainer('table'); + const responseBody = await readResponseBlob(xhr.response.body); + expect(responseBody.data.records.length).to.eq(limit); + }); + cy.get('span.label-danger').contains('10 rows'); + }); + + it('Test table with columns and row limit', () => { + const formData = { + ...VIZ_DEFAULTS, + all_columns: ['name'], + metrics: [], + row_limit: 10, + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); + }); + + it('Test table with columns, ordering, and row limit', () => { + const limit = 10; + + const formData = { + ...VIZ_DEFAULTS, + all_columns: ['name', 'state', 'ds', 'num'], + metrics: [], + row_limit: limit, + order_by_cols: ['["num",+false]'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.wait('@getJson').then(async xhr => { + cy.verifyResponseCodes(xhr); + cy.verifySliceContainer('table'); + const responseBody = await readResponseBlob(xhr.response.body); + const { records } = responseBody.data; + expect(records[0].num).greaterThan(records[records.length - 1].num); + }); + }); + + it('Test table with simple filter', () => { + const metrics = ['count']; + const filters = [SIMPLE_FILTER]; + + const formData = { ...VIZ_DEFAULTS, metrics, adhoc_filters: filters }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' }); + }); + + it('Tests table number formatting with % in metric name', () => { + const PERCENT_METRIC = { + expressionType: 'SQL', + sqlExpression: 'CAST(SUM(sum_girls)+AS+FLOAT)/SUM(num)', + column: null, + aggregate: null, + hasCustomLabel: true, + label: 'Girls', + optionName: 'metric_6qwzgc8bh2v_zox7hil1mzs', + }; + const formData = { + ...VIZ_DEFAULTS, + percent_metrics: PERCENT_METRIC, + groupby: ['state'], + }; + + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: formData.groupby[0], + chartSelector: 'table', + }); + cy.get('td').contains(/\d*%/); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/time_table.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/time_table.js index 6cd4b87f08c02..1ccbc1bcec8bf 100644 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/time_table.js +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/time_table.js @@ -18,118 +18,115 @@ */ import { FORM_DATA_DEFAULTS, NUM_METRIC } from './shared.helper'; -// time table viz +describe('Visualization > Time TableViz', () => { + const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'time_table' }; -export default () => - describe('Time Table Viz', () => { - const VIZ_DEFAULTS = { ...FORM_DATA_DEFAULTS, viz_type: 'time_table' }; - - beforeEach(() => { - cy.login(); - cy.server(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); + beforeEach(() => { + cy.login(); + cy.server(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); - it('Test time series table multiple metrics last year total', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: [NUM_METRIC, 'count'], - column_collection: [ - { - key: '9g4K-B-YL', - label: 'Last+Year', - colType: 'time', - timeLag: '1', - comparisonType: 'value', - }, - ], - url: '', - }; + it('Test time series table multiple metrics last year total', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: [NUM_METRIC, 'count'], + column_collection: [ + { + key: '9g4K-B-YL', + label: 'Last+Year', + colType: 'time', + timeLag: '1', + comparisonType: 'value', + }, + ], + url: '', + }; - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: NUM_METRIC.label, - }); - cy.get('.time-table').within(() => { - cy.get('span').contains('Sum(num)'); - cy.get('span').contains('COUNT(*)'); - }); + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: NUM_METRIC.label, + }); + cy.get('.time-table').within(() => { + cy.get('span').contains('Sum(num)'); + cy.get('span').contains('COUNT(*)'); }); + }); - it('Test time series table metric and group by last year total', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: [NUM_METRIC], - groupby: ['gender'], - column_collection: [ - { - key: '9g4K-B-YL', - label: 'Last+Year', - colType: 'time', - timeLag: '1', - comparisonType: 'value', - }, - ], - url: '', - }; + it('Test time series table metric and group by last year total', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: [NUM_METRIC], + groupby: ['gender'], + column_collection: [ + { + key: '9g4K-B-YL', + label: 'Last+Year', + colType: 'time', + timeLag: '1', + comparisonType: 'value', + }, + ], + url: '', + }; - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: NUM_METRIC.label, - }); - cy.get('.time-table').within(() => { - cy.get('td').contains('boy'); - cy.get('td').contains('girl'); - }); + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: NUM_METRIC.label, + }); + cy.get('.time-table').within(() => { + cy.get('td').contains('boy'); + cy.get('td').contains('girl'); }); + }); - it('Test time series various time columns', () => { - const formData = { - ...VIZ_DEFAULTS, - metrics: [NUM_METRIC, 'count'], - column_collection: [ - { key: 'LHHNPhamU', label: 'Current', colType: 'time', timeLag: 0 }, - { - key: '9g4K-B-YL', - label: 'Last Year', - colType: 'time', - timeLag: '1', - comparisonType: 'value', - }, - { - key: 'JVZXtNu7_', - label: 'YoY', - colType: 'time', - timeLag: 1, - comparisonType: 'perc', - d3format: '%', - }, - { key: 'tN5Gba36u', label: 'Trend', colType: 'spark' }, - ], - url: '', - }; + it('Test time series various time columns', () => { + const formData = { + ...VIZ_DEFAULTS, + metrics: [NUM_METRIC, 'count'], + column_collection: [ + { key: 'LHHNPhamU', label: 'Current', colType: 'time', timeLag: 0 }, + { + key: '9g4K-B-YL', + label: 'Last Year', + colType: 'time', + timeLag: '1', + comparisonType: 'value', + }, + { + key: 'JVZXtNu7_', + label: 'YoY', + colType: 'time', + timeLag: 1, + comparisonType: 'perc', + d3format: '%', + }, + { key: 'tN5Gba36u', label: 'Trend', colType: 'spark' }, + ], + url: '', + }; - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ - waitAlias: '@getJson', - querySubstring: NUM_METRIC.label, - }); - cy.get('.time-table').within(() => { - cy.get('th').contains('Current'); - cy.get('th').contains('Last Year'); - cy.get('th').contains('YoY'); - cy.get('th').contains('Trend'); + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ + waitAlias: '@getJson', + querySubstring: NUM_METRIC.label, + }); + cy.get('.time-table').within(() => { + cy.get('th').contains('Current'); + cy.get('th').contains('Last Year'); + cy.get('th').contains('YoY'); + cy.get('th').contains('Trend'); - cy.get('span').contains('%'); - cy.get('svg') - .first() - .then(charts => { - const firstChart = charts[0]; - expect(firstChart.clientWidth).greaterThan(0); - expect(firstChart.clientHeight).greaterThan(0); - }); - }); + cy.get('span').contains('%'); + cy.get('svg') + .first() + .then(charts => { + const firstChart = charts[0]; + expect(firstChart.clientWidth).greaterThan(0); + expect(firstChart.clientHeight).greaterThan(0); + }); }); }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/treemap.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/treemap.js deleted file mode 100644 index c865262ba30ec..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/treemap.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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 default () => - describe('Treemap', () => { - const TREEMAP_FORM_DATA = { - datasource: '2__table', - viz_type: 'treemap', - slice_id: 50, - granularity_sqla: 'year', - time_grain_sqla: 'P1D', - time_range: '1960-01-01+:+now', - metrics: ['sum__SP_POP_TOTL'], - adhoc_filters: [], - groupby: ['country_code'], - row_limit: 50000, - color_scheme: 'bnbColors', - treemap_ratio: 1.618033988749895, - number_format: '.3s', - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work', () => { - verify(TREEMAP_FORM_DATA); - cy.get('.chart-container svg rect.child').should('have.length', 214); - }); - - it('should work with multiple groupby', () => { - verify({ - ...TREEMAP_FORM_DATA, - groupby: ['region', 'country_code'], - }); - cy.get('.chart-container svg rect.parent').should('have.length', 7); - cy.get('.chart-container svg rect.child').should('have.length', 214); - }); - - it('should work with filter', () => { - verify({ - ...TREEMAP_FORM_DATA, - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'region', - operator: '==', - comparator: 'South Asia', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_8aqxcf5co1a_x7lm2d1fq0l', - }, - ], - }); - cy.get('.chart-container svg rect.child').should('have.length', 8); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/treemap.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/treemap.test.js new file mode 100644 index 0000000000000..3fbd7de4ca0ba --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/treemap.test.js @@ -0,0 +1,84 @@ +/** + * 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. + */ +describe('Visualization > Treemap', () => { + const TREEMAP_FORM_DATA = { + datasource: '2__table', + viz_type: 'treemap', + slice_id: 50, + granularity_sqla: 'year', + time_grain_sqla: 'P1D', + time_range: 'No filter', + metrics: ['sum__SP_POP_TOTL'], + adhoc_filters: [], + groupby: ['country_code'], + row_limit: 50000, + color_scheme: 'bnbColors', + treemap_ratio: 1.618033988749895, + number_format: '.3s', + }; + + const level0 = '.chart-container rect[style="fill: rgb(255, 90, 95);"]'; + const level1 = '.chart-container rect[style="fill: rgb(123, 0, 81);"]'; + const level2 = '.chart-container rect[style="fill: rgb(0, 122, 135);"]'; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work', () => { + verify(TREEMAP_FORM_DATA); + cy.get(level0).should('have.length', 1); + cy.get(level1).should('have.length', 214); + }); + + it('should work with multiple groupby', () => { + verify({ + ...TREEMAP_FORM_DATA, + groupby: ['region', 'country_code'], + }); + cy.get(level0).should('have.length', 1); + cy.get(level1).should('have.length', 7); + cy.get(level2).should('have.length', 214); + }); + + it('should work with filter', () => { + verify({ + ...TREEMAP_FORM_DATA, + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'region', + operator: '==', + comparator: 'South Asia', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_8aqxcf5co1a_x7lm2d1fq0l', + }, + ], + }); + cy.get(level1).should('have.length', 8); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/world_map.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/world_map.js deleted file mode 100644 index 0b60857c1515e..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/world_map.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * 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 default () => - describe('World Map', () => { - const WORLD_MAP_FORM_DATA = { - datasource: '2__table', - viz_type: 'world_map', - slice_id: 45, - granularity_sqla: 'year', - time_grain_sqla: 'P1D', - time_range: '2014-01-01 : 2014-01-02', - entity: 'country_code', - country_fieldtype: 'cca3', - metric: 'sum__SP_RUR_TOTL_ZS', - adhoc_filters: [], - row_limit: 50000, - show_bubbles: true, - secondary_metric: 'sum__SP_POP_TOTL', - max_bubble_size: '25', - }; - - function verify(formData) { - cy.visitChartByParams(JSON.stringify(formData)); - cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); - } - - beforeEach(() => { - cy.server(); - cy.login(); - cy.route('POST', '/superset/explore_json/**').as('getJson'); - }); - - it('should work with ad-hoc metric', () => { - verify(WORLD_MAP_FORM_DATA); - cy.get('.bubbles circle.datamaps-bubble').should('have.length', 206); - }); - - it('should work with simple filter', () => { - verify({ - ...WORLD_MAP_FORM_DATA, - metric: 'count', - adhoc_filters: [ - { - expressionType: 'SIMPLE', - subject: 'region', - operator: '==', - comparator: 'South Asia', - clause: 'WHERE', - sqlExpression: null, - filterOptionName: 'filter_8aqxcf5co1a_x7lm2d1fq0l', - }, - ], - }); - cy.get('.bubbles circle.datamaps-bubble').should('have.length', 8); - }); - - it('should hide bubbles when told so', () => { - verify({ - ...WORLD_MAP_FORM_DATA, - show_bubbles: false, - }); - cy.get('.slice_container').then(containers => { - expect( - containers[0].querySelectorAll('.bubbles circle.datamaps-bubble') - .length, - ).to.equal(0); - }); - }); - }); diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/world_map.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/world_map.test.js new file mode 100644 index 0000000000000..2b44c2e8902a3 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/world_map.test.js @@ -0,0 +1,84 @@ +/** + * 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. + */ +describe('Visualization > World Map', () => { + const WORLD_MAP_FORM_DATA = { + datasource: '2__table', + viz_type: 'world_map', + slice_id: 45, + granularity_sqla: 'year', + time_grain_sqla: 'P1D', + time_range: '2014-01-01 : 2014-01-02', + entity: 'country_code', + country_fieldtype: 'cca3', + metric: 'sum__SP_RUR_TOTL_ZS', + adhoc_filters: [], + row_limit: 50000, + show_bubbles: true, + secondary_metric: 'sum__SP_POP_TOTL', + max_bubble_size: '25', + }; + + function verify(formData) { + cy.visitChartByParams(JSON.stringify(formData)); + cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'svg' }); + } + + beforeEach(() => { + cy.server(); + cy.login(); + cy.route('POST', '/superset/explore_json/**').as('getJson'); + }); + + it('should work with ad-hoc metric', () => { + verify(WORLD_MAP_FORM_DATA); + cy.get('.bubbles circle.datamaps-bubble').should('have.length', 206); + }); + + it('should work with simple filter', () => { + verify({ + ...WORLD_MAP_FORM_DATA, + metric: 'count', + adhoc_filters: [ + { + expressionType: 'SIMPLE', + subject: 'region', + operator: '==', + comparator: 'South Asia', + clause: 'WHERE', + sqlExpression: null, + filterOptionName: 'filter_8aqxcf5co1a_x7lm2d1fq0l', + }, + ], + }); + cy.get('.bubbles circle.datamaps-bubble').should('have.length', 8); + }); + + it('should hide bubbles when told so', () => { + verify({ + ...WORLD_MAP_FORM_DATA, + show_bubbles: false, + }); + cy.get('.slice_container').then(containers => { + expect( + containers[0].querySelectorAll('.bubbles circle.datamaps-bubble') + .length, + ).to.equal(0); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/sqllab/index.test.js b/superset-frontend/cypress-base/cypress/integration/sqllab/index.test.js deleted file mode 100644 index d2273f37052d5..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/sqllab/index.test.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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 queryTests from './query'; -import sourcePanelTests from './sourcePanel'; -import tabsTests from './tabs'; - -describe('All SqlLab tests', () => { - queryTests(); - sourcePanelTests(); - tabsTests(); -}); diff --git a/superset-frontend/cypress-base/cypress/integration/sqllab/query.js b/superset-frontend/cypress-base/cypress/integration/sqllab/query.js deleted file mode 100644 index 71dfe14590658..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/sqllab/query.js +++ /dev/null @@ -1,129 +0,0 @@ -/** - * 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 shortid from 'shortid'; -import { selectResultsTab, assertSQLLabResultsAreEqual } from './sqllab.helper'; - -export default () => { - describe('SqlLab query panel', () => { - beforeEach(() => { - cy.login(); - cy.server(); - cy.visit('/superset/sqllab'); - - cy.route('POST', '/superset/sql_json/').as('sqlLabQuery'); - }); - - it.skip('supports entering and running a query', () => { - // row limit has to be < ~10 for us to be able to determine how many rows - // are fetched below (because React _Virtualized_ does not render all rows) - const rowLimit = 3; - - cy.get('#brace-editor textarea') - .clear({ force: true }) - .type( - `{selectall}{backspace}SELECT ds, gender, name, num FROM main.birth_names LIMIT ${rowLimit}`, - { force: true }, - ); - cy.get('#js-sql-toolbar button').eq(0).click(); - - cy.wait('@sqlLabQuery'); - - selectResultsTab() - .eq(0) // ensures results tab in case preview tab exists - .then(tableNodes => { - const [header, bodyWrapper] = tableNodes[0].childNodes; - const body = bodyWrapper.childNodes[0]; - const expectedColCount = header.childNodes.length; - const expectedRowCount = body.childNodes.length; - expect(expectedColCount).to.equal(4); - expect(expectedRowCount).to.equal(rowLimit); - }); - }); - - it.skip('successfully saves a query', () => { - cy.route('savedqueryviewapi/**').as('getSavedQuery'); - cy.route('superset/tables/**').as('getTables'); - - const query = - 'SELECT ds, gender, name, num FROM main.birth_names ORDER BY name LIMIT 3'; - const savedQueryTitle = `CYPRESS TEST QUERY ${shortid.generate()}`; - - // we will assert that the results of the query we save, and the saved query are the same - let initialResultsTable = null; - let savedQueryResultsTable = null; - - cy.get('#brace-editor textarea') - .clear({ force: true }) - .type(`{selectall}{backspace}${query}`, { force: true }) - .focus() // focus => blur is required for updating the query that is to be saved - .blur(); - - // ctrl + r also runs query - cy.get('#brace-editor textarea').type('{ctrl}r', { force: true }); - - cy.wait('@sqlLabQuery'); - - // Save results to check agains below - selectResultsTab().then(resultsA => { - initialResultsTable = resultsA[0]; - }); - - cy.get('#js-sql-toolbar button') - .eq(1) // save query - .click(); - - // Enter name + save into modal - cy.get('.modal-sm input') - .clear({ force: true }) - .type(`{selectall}{backspace}${savedQueryTitle}`, { - force: true, - }); - - cy.get('.modal-sm .modal-body button') - .eq(0) // save - .click(); - - // visit saved queries - cy.visit('/sqllab/my_queries/'); - - // first row contains most recent link, follow back to SqlLab - cy.get('table tr:first-child a[href*="savedQueryId"').click(); - - // will timeout without explicitly waiting here - cy.wait(['@getSavedQuery', '@getTables']); - - // run the saved query - cy.get('#js-sql-toolbar button') - .eq(0) // run query - .click(); - - cy.wait('@sqlLabQuery'); - - // assert the results of the saved query match the initial results - selectResultsTab().then(resultsB => { - savedQueryResultsTable = resultsB[0]; - - assertSQLLabResultsAreEqual( - initialResultsTable, - savedQueryResultsTable, - ); - }); - }); - }); -}; diff --git a/superset-frontend/cypress-base/cypress/integration/sqllab/query.test.js b/superset-frontend/cypress-base/cypress/integration/sqllab/query.test.js new file mode 100644 index 0000000000000..e4061a3998253 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/sqllab/query.test.js @@ -0,0 +1,124 @@ +/** + * 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 shortid from 'shortid'; +import { selectResultsTab, assertSQLLabResultsAreEqual } from './sqllab.helper'; + +describe('SqlLab query panel', () => { + beforeEach(() => { + cy.login(); + cy.server(); + cy.visit('/superset/sqllab'); + + cy.route('POST', '/superset/sql_json/').as('sqlLabQuery'); + }); + + it.skip('supports entering and running a query', () => { + // row limit has to be < ~10 for us to be able to determine how many rows + // are fetched below (because React _Virtualized_ does not render all rows) + const rowLimit = 3; + + cy.get('#brace-editor textarea') + .clear({ force: true }) + .type( + `{selectall}{backspace}SELECT ds, gender, name, num FROM main.birth_names LIMIT ${rowLimit}`, + { force: true }, + ); + cy.get('#js-sql-toolbar button').eq(0).click(); + + cy.wait('@sqlLabQuery'); + + selectResultsTab() + .eq(0) // ensures results tab in case preview tab exists + .then(tableNodes => { + const [header, bodyWrapper] = tableNodes[0].childNodes; + const body = bodyWrapper.childNodes[0]; + const expectedColCount = header.childNodes.length; + const expectedRowCount = body.childNodes.length; + expect(expectedColCount).to.equal(4); + expect(expectedRowCount).to.equal(rowLimit); + }); + }); + + it.skip('successfully saves a query', () => { + cy.route('savedqueryviewapi/**').as('getSavedQuery'); + cy.route('superset/tables/**').as('getTables'); + + const query = + 'SELECT ds, gender, name, num FROM main.birth_names ORDER BY name LIMIT 3'; + const savedQueryTitle = `CYPRESS TEST QUERY ${shortid.generate()}`; + + // we will assert that the results of the query we save, and the saved query are the same + let initialResultsTable = null; + let savedQueryResultsTable = null; + + cy.get('#brace-editor textarea') + .clear({ force: true }) + .type(`{selectall}{backspace}${query}`, { force: true }) + .focus() // focus => blur is required for updating the query that is to be saved + .blur(); + + // ctrl + r also runs query + cy.get('#brace-editor textarea').type('{ctrl}r', { force: true }); + + cy.wait('@sqlLabQuery'); + + // Save results to check agains below + selectResultsTab().then(resultsA => { + initialResultsTable = resultsA[0]; + }); + + cy.get('#js-sql-toolbar button') + .eq(1) // save query + .click(); + + // Enter name + save into modal + cy.get('.modal-sm input') + .clear({ force: true }) + .type(`{selectall}{backspace}${savedQueryTitle}`, { + force: true, + }); + + cy.get('.modal-sm .modal-body button') + .eq(0) // save + .click(); + + // visit saved queries + cy.visit('/sqllab/my_queries/'); + + // first row contains most recent link, follow back to SqlLab + cy.get('table tr:first-child a[href*="savedQueryId"').click(); + + // will timeout without explicitly waiting here + cy.wait(['@getSavedQuery', '@getTables']); + + // run the saved query + cy.get('#js-sql-toolbar button') + .eq(0) // run query + .click(); + + cy.wait('@sqlLabQuery'); + + // assert the results of the saved query match the initial results + selectResultsTab().then(resultsB => { + savedQueryResultsTable = resultsB[0]; + + assertSQLLabResultsAreEqual(initialResultsTable, savedQueryResultsTable); + }); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/sqllab/sourcePanel.index.js b/superset-frontend/cypress-base/cypress/integration/sqllab/sourcePanel.index.js new file mode 100644 index 0000000000000..011930f3ad348 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/sqllab/sourcePanel.index.js @@ -0,0 +1,77 @@ +/** + * 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 { selectResultsTab } from './sqllab.helper'; + +describe('SqlLab datasource panel', () => { + beforeEach(() => { + cy.login(); + cy.server(); + cy.visit('/superset/sqllab'); + }); + + // TODO the test bellow is flaky, and has been disabled for the time being + // (notice the `it.skip`) + it.skip('creates a table preview when a database, schema, and table are selected', () => { + cy.route('/superset/table/**').as('tableMetadata'); + + // it should have dropdowns to select database, schema, and table + cy.get('.sql-toolbar .Select').should('have.length', 3); + + cy.get('.sql-toolbar .table-schema').should('not.exist'); + cy.get('.SouthPane .tab-content .filterable-table-container').should( + 'not.exist', + ); + + cy.get('.sql-toolbar .Select') + .eq(0) // database select + .within(() => { + // note: we have to set force: true because the input is invisible / cypress throws + cy.get('input').type('main{enter}', { force: true }); + }); + + cy.get('.sql-toolbar .Select') + .eq(1) // schema select + .within(() => { + cy.get('input').type('main{enter}', { force: true }); + }); + + cy.get('.sql-toolbar .Select') + .eq(2) // table select + .within(() => { + cy.get('input').type('birth_names{enter}', { force: true }); + }); + + cy.wait('@tableMetadata'); + + cy.get('.sql-toolbar .table-schema').should('have.length', 1); + selectResultsTab().should('have.length', 1); + + // add another table and check for added schema + preview + cy.get('.sql-toolbar .Select') + .eq(2) + .within(() => { + cy.get('input').type('logs{enter}', { force: true }); + }); + + cy.wait('@tableMetadata'); + + cy.get('.sql-toolbar .table-schema').should('have.length', 2); + selectResultsTab().should('have.length', 2); + }); +}); diff --git a/superset-frontend/cypress-base/cypress/integration/sqllab/sourcePanel.js b/superset-frontend/cypress-base/cypress/integration/sqllab/sourcePanel.js deleted file mode 100644 index ef977b2f7f524..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/sqllab/sourcePanel.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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 { selectResultsTab } from './sqllab.helper'; - -export default () => { - describe('SqlLab datasource panel', () => { - beforeEach(() => { - cy.login(); - cy.server(); - cy.visit('/superset/sqllab'); - }); - - // TODO the test bellow is flaky, and has been disabled for the time being - // (notice the `it.skip`) - it.skip('creates a table preview when a database, schema, and table are selected', () => { - cy.route('/superset/table/**').as('tableMetadata'); - - // it should have dropdowns to select database, schema, and table - cy.get('.sql-toolbar .Select').should('have.length', 3); - - cy.get('.sql-toolbar .table-schema').should('not.exist'); - cy.get('.SouthPane .tab-content .filterable-table-container').should( - 'not.exist', - ); - - cy.get('.sql-toolbar .Select') - .eq(0) // database select - .within(() => { - // note: we have to set force: true because the input is invisible / cypress throws - cy.get('input').type('main{enter}', { force: true }); - }); - - cy.get('.sql-toolbar .Select') - .eq(1) // schema select - .within(() => { - cy.get('input').type('main{enter}', { force: true }); - }); - - cy.get('.sql-toolbar .Select') - .eq(2) // table select - .within(() => { - cy.get('input').type('birth_names{enter}', { force: true }); - }); - - cy.wait('@tableMetadata'); - - cy.get('.sql-toolbar .table-schema').should('have.length', 1); - selectResultsTab().should('have.length', 1); - - // add another table and check for added schema + preview - cy.get('.sql-toolbar .Select') - .eq(2) - .within(() => { - cy.get('input').type('logs{enter}', { force: true }); - }); - - cy.wait('@tableMetadata'); - - cy.get('.sql-toolbar .table-schema').should('have.length', 2); - selectResultsTab().should('have.length', 2); - }); - }); -}; diff --git a/superset-frontend/cypress-base/cypress/integration/sqllab/tabs.js b/superset-frontend/cypress-base/cypress/integration/sqllab/tabs.js deleted file mode 100644 index f4a1f93ebd6ad..0000000000000 --- a/superset-frontend/cypress-base/cypress/integration/sqllab/tabs.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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 default () => { - describe('SqlLab query tabs', () => { - beforeEach(() => { - cy.login(); - cy.server(); - cy.visit('/superset/sqllab'); - }); - - it('allows you to create a tab', () => { - cy.get('#a11y-query-editor-tabs > ul > li').then(tabList => { - const initialTabCount = tabList.length; - - // add tab - cy.get('#a11y-query-editor-tabs > ul > li').last().click(); - - cy.get('#a11y-query-editor-tabs > ul > li').should( - 'have.length', - initialTabCount + 1, - ); - }); - }); - - it('allows you to close a tab', () => { - cy.get('#a11y-query-editor-tabs > ul > li').then(tabListA => { - const initialTabCount = tabListA.length; - - // open the tab dropdown to remove - cy.get('#a11y-query-editor-tabs > ul > li .dropdown-toggle').click(); - - // first item is close - cy.get('#a11y-query-editor-tabs .close-btn a').click(); - - cy.get('#a11y-query-editor-tabs > ul > li').should( - 'have.length', - initialTabCount - 1, - ); - }); - }); - }); -}; diff --git a/superset-frontend/cypress-base/cypress/integration/sqllab/tabs.test.js b/superset-frontend/cypress-base/cypress/integration/sqllab/tabs.test.js new file mode 100644 index 0000000000000..43e9706c25d59 --- /dev/null +++ b/superset-frontend/cypress-base/cypress/integration/sqllab/tabs.test.js @@ -0,0 +1,56 @@ +/** + * 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. + */ +describe('SqlLab query tabs', () => { + beforeEach(() => { + cy.login(); + cy.server(); + cy.visit('/superset/sqllab'); + }); + + it('allows you to create a tab', () => { + cy.get('#a11y-query-editor-tabs > ul > li').then(tabList => { + const initialTabCount = tabList.length; + + // add tab + cy.get('#a11y-query-editor-tabs > ul > li').last().click(); + + cy.get('#a11y-query-editor-tabs > ul > li').should( + 'have.length', + initialTabCount + 1, + ); + }); + }); + + it('allows you to close a tab', () => { + cy.get('#a11y-query-editor-tabs > ul > li').then(tabListA => { + const initialTabCount = tabListA.length; + + // open the tab dropdown to remove + cy.get('#a11y-query-editor-tabs > ul > li .dropdown-toggle').click(); + + // first item is close + cy.get('#a11y-query-editor-tabs .close-btn a').click(); + + cy.get('#a11y-query-editor-tabs > ul > li').should( + 'have.length', + initialTabCount - 1, + ); + }); + }); +}); diff --git a/superset-frontend/cypress-base/package-lock.json b/superset-frontend/cypress-base/package-lock.json index 8f09a65031ab3..25a2aa9530c71 100644 --- a/superset-frontend/cypress-base/package-lock.json +++ b/superset-frontend/cypress-base/package-lock.json @@ -5,11 +5,11 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz", + "integrity": "sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg==", "requires": { - "@babel/highlight": "^7.10.1" + "@babel/highlight": "^7.10.3" } }, "@babel/core": { @@ -34,11 +34,11 @@ } }, "@babel/generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.1.tgz", - "integrity": "sha512-AT0YPLQw9DI21tliuJIdplVfLHya6mcGa8ctkv7n4Qv+hYacJrKmNWIteAK1P9iyLikFIAkwqJ7HAOqIDLFfgA==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.3.tgz", + "integrity": "sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA==", "requires": { - "@babel/types": "^7.10.1", + "@babel/types": "^7.10.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -53,21 +53,21 @@ } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", - "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.3.tgz", + "integrity": "sha512-lo4XXRnBlU6eRM92FkiZxpo1xFLmv3VsPFk61zJKMm7XYJfwqXHsYJTY6agoc4a3L8QPw1HqWehO18coZgbT6A==", "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/helper-explode-assignable-expression": "^7.10.3", + "@babel/types": "^7.10.3" } }, "@babel/helper-builder-react-jsx": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.1.tgz", - "integrity": "sha512-KXzzpyWhXgzjXIlJU1ZjIXzUPdej1suE6vzqgImZ/cpAsR/CC8gUcX4EWRmDfWz/cs6HOCPMBIJ3nKoXt3BFuw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.3.tgz", + "integrity": "sha512-vkxmuFvmovtqTZknyMGj9+uQAZzz5Z9mrbnkJnPkaYGfKTaSsYcjQdXP0lgrWLVh8wU6bCjOmXOpx+kqUi+S5Q==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-builder-react-jsx-experimental": { @@ -81,14 +81,14 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.1.tgz", - "integrity": "sha512-bwhdehBJZt84HuPUcP1HaTLuc/EywVS8rc3FgsEPDcivg+DCW+SHuLHVkYOmcBA1ZfI+Z/oZjQc/+bPmIO7uAA==", - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.3.tgz", + "integrity": "sha512-iRT9VwqtdFmv7UheJWthGc/h2s7MqoweBF9RUj77NFZsg9VfISvBTum3k6coAhJ8RWv2tj3yUjA03HxPd0vfpQ==", + "requires": { + "@babel/helper-function-name": "^7.10.3", + "@babel/helper-member-expression-to-functions": "^7.10.3", + "@babel/helper-optimise-call-expression": "^7.10.3", + "@babel/helper-plugin-utils": "^7.10.3", "@babel/helper-replace-supers": "^7.10.1", "@babel/helper-split-export-declaration": "^7.10.1" } @@ -104,64 +104,64 @@ } }, "@babel/helper-define-map": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", - "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.3.tgz", + "integrity": "sha512-bxRzDi4Sin/k0drWCczppOhov1sBSdBvXJObM1NLHQzjhXhwRtn7aRWGvLJWCYbuu2qUk3EKs6Ci9C9ps8XokQ==", "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/helper-function-name": "^7.10.3", + "@babel/types": "^7.10.3", "lodash": "^4.17.13" } }, "@babel/helper-explode-assignable-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", - "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.3.tgz", + "integrity": "sha512-0nKcR64XrOC3lsl+uhD15cwxPvaB6QKUDlD84OT9C3myRbhJqTMYir69/RWItUvHpharv0eJ/wk7fl34ONSwZw==", "requires": { - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/traverse": "^7.10.3", + "@babel/types": "^7.10.3" } }, "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz", + "integrity": "sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw==", "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/helper-get-function-arity": "^7.10.3", + "@babel/template": "^7.10.3", + "@babel/types": "^7.10.3" } }, "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz", + "integrity": "sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg==", "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-hoist-variables": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", - "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.3.tgz", + "integrity": "sha512-9JyafKoBt5h20Yv1+BXQMdcXXavozI1vt401KBiRc2qzUepbVnd7ogVNymY1xkQN9fekGwfxtotH2Yf5xsGzgg==", "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", - "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz", + "integrity": "sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw==", "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz", + "integrity": "sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w==", "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-module-transforms": { @@ -179,17 +179,17 @@ } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", - "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz", + "integrity": "sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg==", "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==" + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.3.tgz", + "integrity": "sha512-j/+j8NAWUTxOtx4LKHybpSClxHoq6I91DQ/mKgAXn5oNUPIUiGppjPIX3TDtJWPrdfP9Kfl7e4fgVMiQR9VE/g==" }, "@babel/helper-regex": { "version": "7.10.1", @@ -200,15 +200,15 @@ } }, "@babel/helper-remap-async-to-generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", - "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.3.tgz", + "integrity": "sha512-sLB7666ARbJUGDO60ZormmhQOyqMX/shKBXZ7fy937s+3ID8gSrneMvKSSb+8xIM5V7Vn6uNVtOY1vIm26XLtA==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.1", "@babel/helper-wrap-function": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/template": "^7.10.3", + "@babel/traverse": "^7.10.3", + "@babel/types": "^7.10.3" } }, "@babel/helper-replace-supers": { @@ -240,9 +240,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==" + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz", + "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw==" }, "@babel/helper-wrap-function": { "version": "7.10.1", @@ -266,27 +266,27 @@ } }, "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.3.tgz", + "integrity": "sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw==", "requires": { - "@babel/helper-validator-identifier": "^7.10.1", + "@babel/helper-validator-identifier": "^7.10.3", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.1.tgz", - "integrity": "sha512-AUTksaz3FqugBkbTZ1i+lDLG5qy8hIzCaAxEtttU6C0BtZZU9pkNZtWSVAht4EW9kl46YBiyTGMp9xTTGqViNg==" + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.3.tgz", + "integrity": "sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA==" }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", - "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.3.tgz", + "integrity": "sha512-WUUWM7YTOudF4jZBAJIW9D7aViYC/Fn0Pln4RIHlQALyno3sXSjqmTA4Zy1TKC2D49RCR8Y/Pn4OIUtEypK3CA==", "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-remap-async-to-generator": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.3", + "@babel/helper-remap-async-to-generator": "^7.10.3", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, @@ -411,26 +411,26 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", - "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.3.tgz", + "integrity": "sha512-irEX0ChJLaZVC7FvvRoSIxJlmk0IczFLcwaRXUArBKYHCHbOhe57aG8q3uw/fJsoSXvZhjRX960hyeAGlVBXZw==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-define-map": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-define-map": "^7.10.3", + "@babel/helper-function-name": "^7.10.3", + "@babel/helper-optimise-call-expression": "^7.10.3", + "@babel/helper-plugin-utils": "^7.10.3", "@babel/helper-replace-supers": "^7.10.1", "@babel/helper-split-export-declaration": "^7.10.1", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", - "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.3.tgz", + "integrity": "sha512-GWzhaBOsdbjVFav96drOz7FzrcEW6AP5nax0gLIpstiFaI3LOb2tAg06TimaWU6YKOfUACK3FVrxPJ4GSc5TgA==", "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.3" } }, "@babel/plugin-transform-destructuring": { @@ -522,13 +522,13 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", - "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.3.tgz", + "integrity": "sha512-GWXWQMmE1GH4ALc7YXW56BTh/AlzvDWhUNn9ArFF0+Cz5G8esYlVbXfdyHa1xaD1j+GnBoCeoQNlwtZTVdiG/A==", "requires": { - "@babel/helper-hoist-variables": "^7.10.1", + "@babel/helper-hoist-variables": "^7.10.3", "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.3", "babel-plugin-dynamic-import-node": "^2.3.3" } }, @@ -542,9 +542,9 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", - "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.3.tgz", + "integrity": "sha512-I3EH+RMFyVi8Iy/LekQm948Z4Lz4yKT7rK+vuCAeRm0kTa6Z5W7xuhRxDNJv0FPya/her6AUgrDITb70YHtTvA==", "requires": { "@babel/helper-create-regexp-features-plugin": "^7.8.3" } @@ -584,21 +584,21 @@ } }, "@babel/plugin-transform-react-display-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.1.tgz", - "integrity": "sha512-rBjKcVwjk26H3VX8pavMxGf33LNlbocMHdSeldIEswtQ/hrjyTG8fKKILW1cSkODyRovckN/uZlGb2+sAV9JUQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.3.tgz", + "integrity": "sha512-dOV44bnSW5KZ6kYF6xSHBth7TFiHHZReYXH/JH3XnFNV+soEL1F5d8JT7AJ3ZBncd19Qul7SN4YpBnyWOnQ8KA==", "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.3" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.1.tgz", - "integrity": "sha512-MBVworWiSRBap3Vs39eHt+6pJuLUAaK4oxGc8g+wY+vuSJvLiEQjW1LSTqKb8OUPtDvHCkdPhk7d6sjC19xyFw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.3.tgz", + "integrity": "sha512-Y21E3rZmWICRJnvbGVmDLDZ8HfNDIwjGF3DXYHx1le0v0mIHCs0Gv5SavyW5Z/jgAHLaAoJPiwt+Dr7/zZKcOQ==", "requires": { - "@babel/helper-builder-react-jsx": "^7.10.1", + "@babel/helper-builder-react-jsx": "^7.10.3", "@babel/helper-builder-react-jsx-experimental": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.3", "@babel/plugin-syntax-jsx": "^7.10.1" } }, @@ -621,9 +621,9 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", - "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.3.tgz", + "integrity": "sha512-H5kNeW0u8mbk0qa1jVIVTeJJL6/TJ81ltD4oyPx0P499DhMJrTmmIFCmJ3QloGpQG8K9symccB7S7SJpCKLwtw==", "requires": { "regenerator-transform": "^0.14.2" } @@ -673,12 +673,12 @@ } }, "@babel/plugin-transform-template-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", - "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.3.tgz", + "integrity": "sha512-yaBn9OpxQra/bk0/CaA4wr41O0/Whkg6nqjqApcinxM7pro51ojhX6fv1pimAnVjVfDy14K0ULoRL70CA9jWWA==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.3" } }, "@babel/plugin-transform-typeof-symbol": { @@ -754,11 +754,11 @@ }, "dependencies": { "@babel/plugin-proposal-object-rest-spread": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz", - "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.3.tgz", + "integrity": "sha512-ZZh5leCIlH9lni5bU/wB/UcjtcVLgR8gc+FAgW2OOY+m9h1II3ItTO1/cewNUcsIDZSYcSaz/rYVls+Fb0ExVQ==", "requires": { - "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", "@babel/plugin-transform-parameters": "^7.10.1" } @@ -793,37 +793,37 @@ } }, "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.3.tgz", + "integrity": "sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA==", "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/code-frame": "^7.10.3", + "@babel/parser": "^7.10.3", + "@babel/types": "^7.10.3" } }, "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.3.tgz", + "integrity": "sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug==", "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", + "@babel/code-frame": "^7.10.3", + "@babel/generator": "^7.10.3", + "@babel/helper-function-name": "^7.10.3", "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/parser": "^7.10.3", + "@babel/types": "^7.10.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.1.tgz", - "integrity": "sha512-L2yqUOpf3tzlW9GVuipgLEcZxnO+96SzR6fjXMuxxNkIgFJ5+07mHCZ+HkHqaeZu8+3LKnNJJ1bKbjBETQAsrA==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz", + "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==", "requires": { - "@babel/helper-validator-identifier": "^7.10.1", + "@babel/helper-validator-identifier": "^7.10.3", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -872,16 +872,17 @@ } }, "@cypress/code-coverage": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/@cypress/code-coverage/-/code-coverage-3.7.6.tgz", - "integrity": "sha512-uJiI+DmNO8JjoXpXXt0V9nCcVZdb9JfwedQ2tPN8q7g1oyGQ/Cyn52/4GiDwUuny832i8kKhOSxTD/gpDJjy8Q==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@cypress/code-coverage/-/code-coverage-3.8.1.tgz", + "integrity": "sha512-XkecqM/4xHZdAPUMOxOUi5yf2TDWUycqIi6Z6zdGiO9j04CxkRoVTOJYsE14i7uG7orudYSLcLFJEeJv237qXQ==", "requires": { "@cypress/browserify-preprocessor": "3.0.0", "debug": "4.1.1", "execa": "4.0.2", "globby": "11.0.0", "istanbul-lib-coverage": "3.0.0", - "nyc": "15.0.1" + "js-yaml": "3.14.0", + "nyc": "15.1.0" }, "dependencies": { "cross-spawn": { @@ -1064,51 +1065,6 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - } } }, "@istanbuljs/schema": { @@ -1175,9 +1131,9 @@ } }, "acorn": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", - "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==" + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" }, "acorn-node": { "version": "1.8.2", @@ -1190,9 +1146,9 @@ } }, "acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, "aggregate-error": { "version": "3.0.1", @@ -1274,9 +1230,9 @@ } }, "arch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", - "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz", + "integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==", "dev": true }, "archy": { @@ -1755,14 +1711,14 @@ } }, "browserslist": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", - "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.1.tgz", + "integrity": "sha512-WMjXwFtPskSW1pQUDJRxvRKRkeCr7usN0O/Za76N+F4oadaTdQHotSGcX9jT/Hs7mSKPkyMFNvqawB/1HzYDKQ==", "requires": { - "caniuse-lite": "^1.0.30001043", - "electron-to-chromium": "^1.3.413", - "node-releases": "^1.1.53", - "pkg-up": "^2.0.0" + "caniuse-lite": "^1.0.30001088", + "electron-to-chromium": "^1.3.481", + "escalade": "^3.0.1", + "node-releases": "^1.1.58" } }, "buffer": { @@ -1839,9 +1795,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001066", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001066.tgz", - "integrity": "sha512-Gfj/WAastBtfxLws0RCh2sDbTK/8rJuSeZMecrSkNGYxPcv7EzblmDGfWQCFEQcSqYE2BRgQiJh8HOD07N5hIw==" + "version": "1.0.30001088", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001088.tgz", + "integrity": "sha512-6eYUrlShRYveyqKG58HcyOfPgh3zb2xqs7NvT2VVtP3hEUeeWvc3lqhpeMTxYWBBeeaT9A4bKsrtjATm66BTHg==" }, "caseless": { "version": "0.12.0", @@ -2136,9 +2092,9 @@ } }, "commander": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.0.tgz", - "integrity": "sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, "common-tags": { @@ -2290,9 +2246,9 @@ } }, "cypress": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-4.7.0.tgz", - "integrity": "sha512-Vav6wUFhPRlImIND/2lOQlUnAWzgCC/iXyJlJjX9nJOJul5LC1vUpf/m8Oiae870PFPyT0ZLLwPHKTXZNdXmHw==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-4.9.0.tgz", + "integrity": "sha512-qGxT5E0j21FPryzhb0OBjCdhoR/n1jXtumpFFSBPYWsaZZhNaBvc3XlBUDEZKkkXPsqUFYiyhWdHN/zo0t5FcA==", "dev": true, "requires": { "@cypress/listr-verbose-renderer": "0.4.1", @@ -2300,29 +2256,29 @@ "@cypress/xvfb": "1.2.4", "@types/sinonjs__fake-timers": "6.0.1", "@types/sizzle": "2.3.2", - "arch": "2.1.1", + "arch": "2.1.2", "bluebird": "3.7.2", "cachedir": "2.3.0", "chalk": "2.4.2", "check-more-types": "2.24.0", "cli-table3": "0.5.1", - "commander": "4.1.0", + "commander": "4.1.1", "common-tags": "1.8.0", "debug": "4.1.1", - "eventemitter2": "4.1.2", + "eventemitter2": "6.4.2", "execa": "1.0.0", "executable": "4.1.1", "extract-zip": "1.7.0", "fs-extra": "8.1.0", - "getos": "3.1.4", + "getos": "3.2.1", "is-ci": "2.0.0", - "is-installed-globally": "0.1.0", + "is-installed-globally": "0.3.2", "lazy-ass": "1.6.0", "listr": "0.14.3", "lodash": "4.17.15", "log-symbols": "3.0.0", "minimist": "1.2.5", - "moment": "2.24.0", + "moment": "2.26.0", "ospath": "1.2.2", "pretty-bytes": "5.3.0", "ramda": "0.26.1", @@ -2532,9 +2488,9 @@ } }, "electron-to-chromium": { - "version": "1.3.453", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.453.tgz", - "integrity": "sha512-IQbCfjJR0NDDn/+vojTlq7fPSREcALtF8M1n01gw7nQghCtfFYrJ2dfhsp8APr8bANoFC8vRTFVXMOGpT0eetw==" + "version": "1.3.481", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.481.tgz", + "integrity": "sha512-q2PeCP2PQXSYadDo9uNY+uHXjdB9PcsUpCVoGlY8TZOPHGlXdevlqW9PkKeqCxn2QBkGB8b6AcMO++gh8X82bA==" }, "elegant-spinner": { "version": "1.0.1", @@ -2543,9 +2499,9 @@ "dev": true }, "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -2581,6 +2537,11 @@ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" }, + "escalade": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.1.tgz", + "integrity": "sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA==" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -2601,9 +2562,9 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "eventemitter2": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz", - "integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU=", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.2.tgz", + "integrity": "sha512-r/Pwupa5RIzxIHbEKCkNXqpEQIIT4uQDxmP4G/Lug/NokVUWj0joz/WzWl3OxRpC5kDrH/WdiUJoR+IrwvXJEw==", "dev": true }, "events": { @@ -2815,15 +2776,15 @@ "dev": true }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", - "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2957,11 +2918,12 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "for-in": { @@ -3129,12 +3091,12 @@ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getos": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.4.tgz", - "integrity": "sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", "dev": true, "requires": { - "async": "^3.1.0" + "async": "^3.2.0" } }, "getpass": { @@ -3179,12 +3141,12 @@ } }, "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", "dev": true, "requires": { - "ini": "^1.3.4" + "ini": "^1.3.5" } }, "globals": { @@ -3381,9 +3343,9 @@ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "ignore": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.6.tgz", - "integrity": "sha512-cgXgkypZBcCnOgSihyeqbo6gjIaIyDqPQB7Ra4vhE9m6kigdGoQDMHjviFhRZo3IMlRy6yElosoviMs5YxZXUA==" + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, "imurmurhash": { "version": "0.1.4", @@ -3549,13 +3511,13 @@ } }, "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", "dev": true, "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" } }, "is-number": { @@ -3586,13 +3548,10 @@ } }, "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true }, "is-plain-object": { "version": "2.0.4", @@ -3670,18 +3629,18 @@ }, "dependencies": { "@babel/core": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.1.tgz", - "integrity": "sha512-u8XiZ6sMXW/gPmoP5ijonSUln4unazG291X0XAQ5h0s8qnAFr6BRRZGUEK+jtRWdmB0NTJQt7Uga25q8GetIIg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.3.tgz", + "integrity": "sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w==", "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", + "@babel/code-frame": "^7.10.3", + "@babel/generator": "^7.10.3", "@babel/helper-module-transforms": "^7.10.1", "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/parser": "^7.10.3", + "@babel/template": "^7.10.3", + "@babel/traverse": "^7.10.3", + "@babel/types": "^7.10.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -4061,12 +4020,11 @@ } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -4197,9 +4155,9 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "micromatch": { "version": "3.1.10", @@ -4331,9 +4289,9 @@ } }, "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", + "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==", "dev": true }, "ms": { @@ -4385,9 +4343,9 @@ } }, "node-releases": { - "version": "1.1.57", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.57.tgz", - "integrity": "sha512-ZQmnWS7adi61A9JsllJ2gdj2PauElcjnOwTp2O011iGzoakTxUsDGSe+6vD7wXbKdqhSFymC0OSx35aAMhrSdw==" + "version": "1.1.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", + "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==" }, "normalize-path": { "version": "3.0.0", @@ -4410,9 +4368,9 @@ "dev": true }, "nyc": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.1.tgz", - "integrity": "sha512-n0MBXYBYRqa67IVt62qW1r/d9UH/Qtr7SF1w/nQLJ9KxvWF6b2xCHImRAixHN9tnMMYHC2P14uo6KddNGwMgGg==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "requires": { "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", @@ -4422,6 +4380,7 @@ "find-cache-dir": "^3.2.0", "find-up": "^4.1.0", "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", "glob": "^7.1.6", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-hook": "^3.0.0", @@ -4442,39 +4401,6 @@ "yargs": "^15.0.2" }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, "p-map": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", @@ -4483,16 +4409,6 @@ "aggregate-error": "^3.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -4614,19 +4530,19 @@ "dev": true }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" } }, "p-map": { @@ -4636,9 +4552,9 @@ "dev": true }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-hash": { "version": "4.0.0", @@ -4693,21 +4609,15 @@ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -4730,9 +4640,9 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -4770,59 +4680,6 @@ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "requires": { "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - } - } - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "requires": { - "find-up": "^2.1.0" } }, "posix-character-classes": { @@ -4972,9 +4829,9 @@ } }, "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", + "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==" }, "regenerate-unicode-properties": { "version": "8.2.0", @@ -4999,9 +4856,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz", - "integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", + "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -6061,54 +5918,11 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", diff --git a/superset-frontend/cypress-base/package.json b/superset-frontend/cypress-base/package.json index 54d3810263106..d021910a15a66 100644 --- a/superset-frontend/cypress-base/package.json +++ b/superset-frontend/cypress-base/package.json @@ -10,10 +10,10 @@ "license": "Apache-2.0", "dependencies": { "shortid": "^2.2.15", - "@cypress/code-coverage": "^3.7.6" + "@cypress/code-coverage": "^3.8.1" }, "devDependencies": { - "cypress": "4.7.0", + "cypress": "4.9.0", "eslint-plugin-cypress": "^2.11.1" } }